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


von hans (Gast)


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.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use ieee.numeric_std.all;
4
5
entity MainComputer is
6
  port ( 
7
    clock : in     STD_LOGIC;
8
    reset : in     STD_LOGIC;
9
    SW   : in     STD_LOGIC_VECTOR(0 to 3);
10
    GP_IO : inout   STD_LOGIC_VECTOR(0 to 3);
11
    KEY   : in     STD_LOGIC;
12
    LEDG   : out   STD_LOGIC_VECTOR(0 to 3)
13
    );
14
end MainComputer;
15
16
architecture rtl of MainComputer is 
17
--internal signal declaration
18
type state_t is (S_IDLE, S_COUNT, S_COUNT2, S_LED, S_LED2);
19
  signal count,count_nxt : unsigned(29 downto 0);  
20
  signal state, state_nxt: state_t;
21
  
22
begin
23
24
  process(clock, reset)
25
  begin
26
    -- asynchronous reset
27
    if reset   = '1' then
28
      count         <= (others => '0');
29
      state         <= S_IDLE;
30
    elsif rising_edge(clock) then
31
      count         <= count_nxt;
32
      state         <= state_nxt;
33
      
34
    end if;
35
  end process;
36
  
37
--logic connections between internal signals
38
  process (clock,state,key,count)
39
  begin
40
  case state is
41
  
42
  when S_IDLE =>
43
  if key = '1' then
44
  state_nxt <= S_COUNT;
45
  end if;
46
  
47
  when S_COUNT => 
48
  count_nxt <= count + to_unsigned(1, count'length);
49
  if count = to_unsigned(100000000, count'length) then
50
  count_nxt <= (others => '0');
51
  state_nxt <= S_LED;
52
  end if;
53
  
54
  when S_LED => 
55
  LEDG <= "1100";
56
  state_NXT <= S_COUNT2;
57
  
58
  
59
  when S_COUNT2 => 
60
  count_nxt <= count + to_unsigned(1, count'length);
61
  if count = to_unsigned(100000000, count'length) then
62
  count_nxt <= (others => '0');
63
  state_nxt <= S_LED2;
64
  end if;
65
  
66
  when S_LED2 => 
67
  LEDG <= "0011";
68
  state_nxt <= S_IDLE;
69
70
  
71
72
73
  end case;
74
  end process;
75
end rtl;

Vielen Dank im voraus.

Gruß

: Verschoben durch Moderator
von Bernhard S. (b_spitzer)


Lesenswert?

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

von Achim S. (Gast)


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.

von Forist (Gast)


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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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
von Christoph (Gast)


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.
1
process (state,key,count)
2
  begin
3
4
  -- Default Wert zuweisen
5
  LEDG <= "0000";
6
7
  case state is
8
  ...

von Achim S. (Gast)


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.

von hans (Gast)


Lesenswert?

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

von Christoph (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.