mikrocontroller.net

Forum: FPGA, VHDL & Co. LED-Blink VHDL


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe ein Problem: Ich versuche 4 LEDs kurz blinken zu lassen. Als 
erstes LED 1-2 und anschließend LED 3-4. Das findet dann auf dem 
DE0-Nano Board statt. Leider bekomme ich die Warnung:

Warning (332060): Node: state.S_LED was determined to be a clock but was 
found without an associated clock assignment.
Info (13166): Latch LEDG[1]$latch is being clocked by state.S_LED

Außderdem befinden sich noch Latches im Code:

Warning (335093): TimeQuest Timing Analyzer is analyzing 37 
combinational loops as latches. For more details, run the Check Timing 
command in the TimeQuest Timing Analyzer or view the "User-Specified and 
Inferred Latches" table in the Analysis & Synthesis report.

Leider verstehe ich die Warnungen nicht recht. Vielleicht kann mir ja 
jemand weiterhelfen.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity MainComputer is
  port ( 
    clock : in     STD_LOGIC;
    reset : in     STD_LOGIC;
    SW   : in     STD_LOGIC_VECTOR(0 to 3);
    GP_IO : inout   STD_LOGIC_VECTOR(0 to 3);
    KEY   : in     STD_LOGIC;
    LEDG   : out   STD_LOGIC_VECTOR(0 to 3)
    );
end MainComputer;

architecture rtl of MainComputer is 
--internal signal declaration
type state_t is (S_IDLE, S_COUNT, S_COUNT2, S_LED, S_LED2);
  signal count,count_nxt : unsigned(29 downto 0);  
  signal state, state_nxt: state_t;
  
begin

  process(clock, reset)
  begin
    -- asynchronous reset
    if reset   = '1' then
      count         <= (others => '0');
      state         <= S_IDLE;
    elsif rising_edge(clock) then
      count         <= count_nxt;
      state         <= state_nxt;
      
    end if;
  end process;
  
--logic connections between internal signals
  process (clock,state,key,count)
  begin
  case state is
  
  when S_IDLE =>
  if key = '1' then
  state_nxt <= S_COUNT;
  end if;
  
  when S_COUNT => 
  count_nxt <= count + to_unsigned(1, count'length);
  if count = to_unsigned(100000000, count'length) then
  count_nxt <= (others => '0');
  state_nxt <= S_LED;
  end if;
  
  when S_LED => 
  LEDG <= "1100";
  state_NXT <= S_COUNT2;
  
  
  when S_COUNT2 => 
  count_nxt <= count + to_unsigned(1, count'length);
  if count = to_unsigned(100000000, count'length) then
  count_nxt <= (others => '0');
  state_nxt <= S_LED2;
  end if;
  
  when S_LED2 => 
  LEDG <= "0011";
  state_nxt <= S_IDLE;

  


  end case;
  end process;
end rtl;


Vielen Dank im voraus.

Gruß

: Verschoben durch Moderator
Autor: Bernhard S. (b_spitzer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Clock hat beim 2. Prozess in der Sensitivity-Liste nichts zu suchen. Das 
ist ein Schaltnetz, kein Schaltwerk.

Autor: Achim S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hans schrieb:
> Außderdem befinden sich noch Latches im Code:

die kannst du vermeiden, indem du im zweiten Prozess in jedem 
möglichen Zustand jedem benutzten Signal eine Zuweisung gibst.

Z.B. in S_IDLE erfolgt keine Zuweisung an LEDG und count_nxt, also muss 
sich in diesem Fall der bisherige Wert von LEDG und count_nxt gemerkt 
werden (in einem LAtch).

Ggf. braucht deine case-Struktur dann auch noch ein when others. Und ein 
Signal LEDG_nxt.

Autor: Forist (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit VHDL beißt du bei den meisten Mikrocontrollern auf Granit.

Hast du schon mal daran gedacht, dein Problem in einem FPGA-Forum 
vorzutragen?

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hans schrieb:
> Außderdem befinden sich noch Latches im Code
Du müsstest eigentlich auch für die LEDs mit einem LEDG_nxt Signal 
arbeiten und wie bei dem Zähler im getakteten Prozess die Zuweisung an 
LEDG machen.
Latches im Design sind besonders dann so unkalkulierbar, wenn davor 
irgendeine Kombinatorik sitzt, die wie z.B. die Weiterschaltlogik einer 
FAM oder eines Zählers "Glichtes" erzeugen kann. Dann speichern die 
Latches nämlich beliebige Werte (es kann auch sein, dass der Glitch so 
kurz ist, dass nur ein Teil der Latches den mitbekommt und falsche Werte 
speichert) und daraus resultiert dann meist beliebiges fehlerhaftes 
Verhalten.

> Vielleicht kann mir ja jemand weiterhelfen.
Das Thema "Off by One" solltest du auch mal googeln: dein Zähler braucht 
real 100000001 Takte. Gut, das ist hier jetzt nicht so arg, aber wenn du 
mal nur auf 10 zählen willst, dann hast du 10% Fehler.

Achim S. schrieb:
> die kannst du vermeiden, indem du im zweiten Prozess in jedem_ möglichen
> Zustand _jedem benutzten Signal eine Zuweisung gibst.
Oder indem du mit der Ein-Prozess-Schreibweise arbeitest. Dann passiert 
sowas garantiert nicht:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
Und das mit der möglicherweise auftretenden Latency bekommt man mit ein 
wenig Brainstorming dann recht schnell kapiert.

: Bearbeitet durch Moderator
Autor: Christoph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> hans schrieb:
>> Außderdem befinden sich noch Latches im Code
> Du müsstest eigentlich auch für die LEDs mit einem LEDG_nxt Signal
> arbeiten und wie bei dem Zähler im getakteten Prozess die Zuweisung an
> LEDG machen.

Das ist die zu bevorzugende Variante in FPGAs aus den genannten Gründen.


Achim S. schrieb:
> hans schrieb:
>> Außderdem befinden sich noch Latches im Code:
>
> die kannst du vermeiden, indem du im zweiten Prozess in jedem
> möglichen Zustand jedem benutzten Signal eine Zuweisung gibst.

Es geht auch etwas einfacher, wenn man vor dem case Statement dem Signal 
LEDG einen default Wert zuweist. Innerhalb eines Prozesses "gewinnt" die 
letzte Zuweisung an ein Signal.
process (state,key,count)
  begin

  -- Default Wert zuweisen
  LEDG <= "0000";

  case state is
  ...

Autor: Achim S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph schrieb:
> Es geht auch etwas einfacher, wenn man vor dem case Statement dem Signal
> LEDG einen default Wert zuweist. Innerhalb eines Prozesses "gewinnt" die
> letzte Zuweisung an ein Signal.

Das vermeidet zwar die Latches, aber daraus ergibt sich dann eine andere 
Funktion als der TO eigentlich möchte. Er will ja tatsächlich für einige 
Kombinationen der Eingangssignale den Wert von LEDG speichern - nur 
sollte das eben in Flip-Flops und nicht in Latches passieren.

Mit der Defaultzuweisung zu Beginn des Prozesses würde er LEDG eben 
nicht speichern sondern auf den Default-Wert setzen.

Autor: hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, vielen dank für eurer Feedback. Ich werde eure Tipps in den Code 
implementieren.

Autor: Christoph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achim S. schrieb:
> Das vermeidet zwar die Latches, aber daraus ergibt sich dann eine andere
> Funktion als der TO eigentlich möchte. Er will ja tatsächlich für einige
> Kombinationen der Eingangssignale den Wert von LEDG speichern - nur
> sollte das eben in Flip-Flops und nicht in Latches passieren.

hans schrieb:
> Ich habe ein Problem: Ich versuche 4 LEDs kurz blinken zu lassen.

Er hat gesagt kurz :-) Wie so dann etwas speichern...

Ich gebe dir recht, dass der LED Zustand gespeichert werden soll um das 
zu bekommen, was die meisten mit so einem LED blinker wollen. Es war 
auch mehr zur Ergänzung wie man die Latches mit weniger Schreibarbeit 
vermeiden kann.

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.