mikrocontroller.net

Forum: FPGA, VHDL & Co. Implementierung einer Figur


Autor: zakar95 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute!

Ich bin noch recht neu in VHDL und probiere mich gerade an ein paar 
Aufgaben und wollte euch diesbezüglich etwas fragen.

Zunächst einmal die Aufgabenstellung:

Insgesamt geht es darum, eine Figur zu bauen. Diese hat einen 
Bewegungsmelder, eine Lampe für Augen und einen Lautsprecher, der Laute 
abgeben kann. Weiterhin hat diese Figur einen Taktgeber, d. h. es gilt
entity figur is
    port (clock    : in STD_LOGIC;  -- the clock has every second a rising edge
          melder : in STD_LOGIC;  -- motion sensor
          lichter   : out STD_LOGIC; -- the lamps for the eyes
          lautsprecher : out STD_LOGIC  -- the speaker for chain rattling
         );
end figur;
Wenn eine steigende Flanke kommt, werden Eingaben überprüft. Die Figur 
soll sich aktivieren, wenn der Bewegungsmelder ein Signal bekommt, wobei 
der Lautsprecher dann ebenfalls sofort starten soll. 5 Sekunden später 
wiederum sollen die Augen dann beginnen, zu leuchten. Wenn der Melder 
kein Signal mehr meldet, so soll zuerst das Leuchten und die Laute des 
Sprechers noch 20 Sekunden fortgesetzt werden, anschließend wird der 
Lautsprecher ausgeschaltet und 15 Sekunden später wird dann das Leuchten 
der Augen ausgeschaltet.

Aktuell habe ich gemäß der Beschreibung nach eigener Interpretation es 
folgendermaßen implementiert:
architecture Behavioral of figur is
begin
    activate : process (clock)
    variable counter : integer range 0 to 40 := 0;
    begin
      if rising_edge(clock) then
        if (melder = 1) then
          lautsprecher <= '1';
          if (counter = 5) then
            lichter <= '1';
          end if;
        else
          if (counter = 25) then
            lautsprecher <= '0';
          end if;
          if (counter = 40) then
            lichter <= '0';
          end if;
        end if;
      end if;
      counter := counter + 1;
    end process;
end Behavioral;
Meine Idee hierbei war, einen counter als Variable zu benutzen (für die 
Sekunden). Mich würde nun einmal interessieren, ob der Ansatz so richtig 
ist bzw. was man genau wo verbessern kann.

: Bearbeitet durch Moderator
Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zakar95 schrieb:
> entity figur is
>   port (clock : in STD_LOGIC;  -- the clock has every second a rising edge
Das ist aber kein Design fürs echte Leben, oder? Denn dort hat ein FPGA 
einen Takt im Bereich ab 50MHz aufwärts...

> Die Figur soll sich aktivieren, wenn der Bewegungsmelder ein Signal
> bekommt, wobei der Lautsprecher dann ebenfalls sofort starten soll.
Und wenn sich der Bewegungsmelder für 0,9 Sekunden genau zwischen zwei 
Taktimpulsen regt?

> Meine Idee hierbei war, einen counter als Variable zu benutzen
Warum unnötigerweise eine Variable?
Siehe den Beitrag "Variable vs Signal"

> Wenn der Melder kein Signal mehr meldet, so soll zuerst das Leuchten und
> die Laute des Sprechers noch 20 Sekunden fortgesetzt werden
Solltest du dann bei aktivem Melder nicht irgendwie den Counter 
zurücksetzen?

Mein Tipp: simuliere dein Design einfach mal. Dort kannst du dann ganz 
einfach kontrollieren ob es funktioniert und wenn nicht, was wo schief 
läuft.

> was man genau wo verbessern kann.
Du kannst den Quelltext hier wie in der Bedieungsanleitung nach "Antwort 
schreiben - Wichtige Regeln- erst lesen, dann posten!" beschrieben mit 
den [vhdl]-Tags umrahmen...

Autor: ElKo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
[...]
    variable counter : integer range 0 to 40 := 0;
[...]
      counter := counter + 1;
[...]
Kurze Zwischenfrage: Wenn der Counter überläuft, geht es bei VHDL 
automatisch bei 0 (bzw. beim Minimum) wieder los?

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem hatte ich genau hier

Beitrag "Re: VHDL Grundlagen"

schon mal.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ElKo schrieb:
> Kurze Zwischenfrage: Wenn der Counter überläuft, geht es bei VHDL
> automatisch bei 0 (bzw. beim Minimum) wieder los?
Nein.
1. Der Simulator gibt einem Fehler aus.
2. Die reale Hardware zählt bis 63 und läuft dann über auf 0.

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei Integer zählt der Zähler in der Simulation einfach endlos weiter 
nach oben.

Autor: ElKo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super. Danke für die Klarstellung.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gustl B. schrieb:
> Bei Integer zählt der Zähler in der Simulation einfach endlos weiter
> nach oben.
Aber eben nicht bei einem eingeschränkten Integer wie hier. Da hält 
der Simulator mit einem Fehler bei 41 an. Und genau deshalb sollte man 
auch solche Bereiche (0 to 40) angeben, denn nur der Designer weiß, dass 
für diesen Zähler eine Wert von 1234567 unsinnig ist.

Im realen FPGA brauchen 0..40 letztlich einen 6 Bit breiten Zähler. Und 
weil kein Überlauf abgehandelt wird, zählt der Zähler auf diesen 6 Bits 
laufend weiter. Und da kommt nach 63 dann eben die 0.

zakar95 schrieb:
> Die Figur soll sich aktivieren...
Was soll denn passieren, wenn der Melder nach dem Abschalten schon nach 
15 Sekunden wieder aktiviert wird? Oder nach 25?

Du musst übrigens bedenken, dass der Melder auch mal 60 Sekunden belegt 
sein kann. Was soll dann passieren? Laut deiner Beschreibung muss 
solange dann sowohl die Leuchte wie auch der Lautsprecher aktiviert 
sein.

Ich würde hier jetzt erst mal die zusammengemantschte Aufgabe in 2 
Teilaufgaben trennen: das Leuchten und den Lautsprecher.
1. Lautsprecher
Für den Lautsprecher wird es ganz einfach: der bekommt einen eigenen 
Timer, der bei aktivem Melder laufend auf 20 gesetzt und bei inaktivem 
Melder heruntergezählt wird. Solange der Timer ungleich 0 ist wird der 
Lautsprecher aktiviert.
2. Leuchten
Diese Aufgabe packst du am einfachsten in einen Zustandsautomaten. In 
dessen Ruhezustand wird der Leuchtenzähler auf 0 gesetzt und gewartet, 
bis der Melder aktiviert wird. Im nächsten Zustand wird der Zähler 
hochgezählt und bei Erreichen des Verzögerungswertes die LEDs 
eingeschaltet. Dann wird im nächsten Zustand gewartet, bis das 
Meldersignal wieder inaktiv wird und die Leuchte verzögert abgeschaltet.

: Bearbeitet durch Moderator
Autor: -gb- (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Aber eben nicht bei einem eingeschränkten Integer wie hier. Da hält
> der Simulator mit einem Fehler bei 41 an. Und genau deshalb sollte man
> auch solche Bereiche (0 to 40) angeben, denn nur der Designer weiß, dass
> für diesen Zähler eine Wert von 1234567 unsinnig ist.

Nein. Gerade getestet mit VIVADO und dem dortigen Simulator.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;

entity spielwiese is Port(
  clk : in std_logic;
  output: out std_logic_vector(7 downto 0));
end spielwiese;

architecture Behavioral of spielwiese is

signal counter: integer range 0 to 15:=0;

begin

process begin
  wait until rising_edge(clk);
  counter <= counter +1;
end process;

output <= std_logic_vector(to_unsigned(counter,8));

end Behavioral;

Und die Testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;

entity spielwiese_bench is
end spielwiese_bench;

architecture Behavioral of spielwiese_bench is

component spielwiese is Port(
  clk : in std_logic;
  output: out std_logic_vector(7 downto 0));
end component;

signal clk: std_logic:='0';
signal output: std_logic_vector(7 downto 0):=(others => '0');

begin

clk <= not clk after 5 ns;

uut: spielwiese port map(
  clk => clk,
  output => output);

end Behavioral;

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-gb- schrieb:
> VIVADO und dem dortigen Simulator
Der taugt offensichtlich nix.

Bei Modelsim sieht es so aus:
# vsim spielwiese_bench
# Start time: 11:02:19 on Nov 02,2017
# ** Note: (vsim-3812) Design is being optimized...
#
# //  ModelSim SE-64 10.3d Oct  7 2014
# //
# //  Copyright 1991-2014 Mentor Graphics Corporation
# //  All Rights Reserved.
# //
# //  THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION
# //  WHICH IS THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS
# //  LICENSORS AND IS SUBJECT TO LICENSE TERMS.
# //
# Loading std.standard
# Loading std.textio(body)
# Loading ieee.std_logic_1164(body)
# Loading ieee.numeric_std(body)
# Loading work.spielwiese_bench(behavioral)#1
run -all
run -all
# ** Fatal: (vsim-3421) Value 16 is out of range 0 to 15.
#    Time: 155 ns  Iteration: 0  Process: /spielwiese_bench/uut/line__16 File: int.vhd
# Fatal error in Process line__16 at int.vhd line 18
#
# HDL call sequence:
# Stopped at int.vhd 18 Process line__16
#

Duke

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mag sein, dass der nichts taugt, ist aber einfach zu bedienen und gerade 
Anfänger die sich das VIVADO runterladen werden den verwenden, für die 
ist es nicht offensichtlich, dass das nichts taugt. So wie ich ja auch. 
Bei Integer finde ich das Verhalten sogar noch logisch, wieso sollte das 
irgendwann wieder bei 0 anfangen? Das ist ja nicht auf eine bestimmte 
Anzahl an Bits beschränkt. Wünschenswert wäre eine Warnung wenn ein 
beschränkter Integer über die Schranke läuft, aber ... wenn es diese 
Warnung gäbe, dann auch nur in der Simulation. In Hardware fängt der 
Zähler an wenn alle Bits 1 sind aber nicht wenn eine Schranke 
Beschränkung überschritten wird.
Wenn, dann will ich also, dass die Simulation genauso wie die Hardware 
funktioniert, also der die das Integer erst dann überläuft wenn alle 
Bits gesetzt sind. Und dafür gibt es die Post-Syntheses Functional 
Simulation, die nutze ich dann auch relativ häufig wobei auch die 
normale Simulation OK ist wenn man weiß was sie macht.

Autor: Alexander F. (alexf91)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
GHDL bricht auch ab:
./spielwiese_bench:error: bound check failure at spielwiese.vhd:18
./spielwiese_bench:error: simulation failed

Autor: Duke Scarring (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Gustl B. schrieb:
> Mag sein, dass der nichts taugt, ist aber einfach zu bedienen und
> gerade
> Anfänger die sich das VIVADO runterladen werden den verwenden, für die
> ist es nicht offensichtlich, dass das nichts taugt.
Ja, leider. Schade das der Vivadosimulator sich nicht an den 
VHDL-Standard hält.

> Bei Integer finde ich das Verhalten sogar noch logisch, wieso sollte das
> irgendwann wieder bei 0 anfangen?
Es sollte wieder bei -2^31 anfangen. Das sieht zumindest der Standard 
vor.

> Wünschenswert wäre eine Warnung wenn ein
> beschränkter Integer über die Schranke läuft, aber ... wenn es diese
> Warnung gäbe, dann auch nur in der Simulation. In Hardware fängt der
> Zähler an wenn alle Bits 1 sind aber nicht wenn eine Schranke
> Beschränkung überschritten wird.
Richtig.

> Wenn, dann will ich also, dass die Simulation genauso wie die Hardware
> funktioniert, also der die das Integer erst dann überläuft wenn alle
> Bits gesetzt sind. Und dafür gibt es die Post-Syntheses Functional
> Simulation, die nutze ich dann auch relativ häufig wobei
Ich nicht. Ich erwarte vom Simulator eine korrekte Funktionsweise.
Wenn ich Überläufe zulassen will, dann nehme ich entweder 
signed/unsigned oder Modulo bei Integer.
Dann läuft die Verhaltenssimulation identisch zur Hardware. Ohne 
Fehlermeldung und ohne die unnötige Post-Synthesis-Simulation.

Duke

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Ich hätte lieber, dass das Synthesetool auch beschränkte Integer richtig 
in Hardware umwandelt. Wieso sollte man sonst überhaupt Integers 
beschränken? Weil das eben keinen Sinn ergibt und ungenutzte Bits 
sowieso wegoptimiert werden könnte man die Beschränkung ganz weglassen. 
Ich beschränke schon, aber nur auf 2^n-1.

Aber wo wir schon dabei sind:
Wenn ich jetzt einen ungerade beschränkten Integer für die Zustände 
einer FSM verwende, also integer range 0 to 5.

Und dann verwende ich in der FSM auch alle 6 Zustände 0 bis 5, denke mir 
jawohl, es gibt jetzt keine Zustände die nicht abgedeckt sind und liege 
falsch, es werden nämlich 3 Bits für die Zustände verwendet, 8 Zustände 
und nur 6 sind abgedeckt. Klar mit when others wird das gelöst, aber was 
hat dann die Beschränkung gebracht?

Autor: Duke Scarring (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Gustl B. schrieb:
> Und dann verwende ich in der FSM auch alle 6 Zustände 0 bis 5, denke mir
> jawohl, es gibt jetzt keine Zustände die nicht abgedeckt sind und liege
> falsch, es werden nämlich 3 Bits für die Zustände verwendet, 8 Zustände
> und nur 6 sind abgedeckt
Jupp und wenn der Synthesizer der Meinung ist auf one-hot zu kodieren 
hast Du 6 Bits und 58 ungültige Zustände. Da hilft auch when others 
nicht.

Meine Zustände haben übrigens Namen:
  type state_t is (IDLE, DOSOMETHING, DOSOMETHINGOTHER, READY);

Finde ich besser als
  type s16_type is ( S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, S16);
(und dabei handelte es sich um Code, mit dem Geld verdient wurde...)

Duke

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Duke Scarring schrieb:
> -gb- schrieb:
>> VIVADO und dem dortigen Simulator
> Der taugt offensichtlich nix.
Die Defaultwerte sind da ganz offensichtlich völlig untauglich 
eingestellt.
Das hatten wir schon mal im 
Beitrag "Re: VGA Versuch - Problem beim Simulieren"
Ich habe das allerdings nicht weiter untersucht...

Gustl B. schrieb:
> Wieso sollte man sonst überhaupt Integers beschränken?
Weil nur du als Entwickler wei0t, dass ein VGA-Zähler nur auf 639 oder 
479 laufen muss. Sobald er größere Werte erreicht, ist das ein Fehler, 
denn das war nicht so geplant.

> Weil das eben
> keinen Sinn ergibt und ungenutzte Bits sowieso wegoptimiert werden
Aber erst weit hinten in der Toolchain mit vielen Meldungen zu "unused 
signals". Wenn man den range mit angibt, dann kann schon der Synthesizer 
die unnötigen Leitungen weglassen. Siehe 
Beitrag "Re: VGA Versuch - Problem beim Simulieren"

: Bearbeitet durch Moderator
Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Weil nur du als Entwickler wei0t, dass ein VGA-Zähler nur auf 639 oder
> 479 laufen muss.

Ja, aber der Entwickler muss den Zähler dann auch im Code zurücksetzen.

Da mir das VIVADO da sowieso keinen Fehler ausspuckt habe ich sowas 
immer händisch in der Testbench abgeprüft oder eben auf die Signale 
geachtet und mal hingeguckt ob da Fehler passieren.

Also ja, wenn der Simulator da einen Fehler meldet sollte man das machen 
weil es aus Debugginggründen sinnvoll ist, das verstehe ich.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.