Forum: FPGA, VHDL & Co. Einfaches VHDL-Problem: LATTICE FPGA


von ITSE (Gast)


Lesenswert?

Hi, ich hab ein kleines Testboard mit nem FPGA und 4 LEDs.... Die 
leuchten auch wenn man ihnen ne '1' zuweist und gehen aus bei ner '0'. 
Nun habe ich es geschafft mittels eines externen Quartzoszillators (16 
MHz) alle 4 LEDs zum blinken zu bringen. (Blinken alle zusammen). Dazu 
habe ich folgenden Code geschrieben. Ich möchte jedoch ein Lauflicht 
machen und das geht einfach nicht. Die LEDs bleiben aus.... Dafür muss 
ich nur eine Zeile auskommentieren und die andere rein tun... siehe die 
einzigste auskommentierte Zeile.... Hat jemand eine Ahnung?

Danke schon mal...


1
SIGNAL intern : std_logic_vector(3 DOWNTO 0);
2
3
...
4
5
led0 <= intern(3);
6
led1 <= intern(2);
7
led2 <= intern(1);
8
led3 <= intern(0);
9
10
 
11
12
 p1: PROCESS (clk)
13
 VARIABLE zaehl : integer := 0;
14
 VARIABLE beg : boolean := true;
15
 
16
17
 BEGIN
18
 IF beg = true THEN
19
  intern <= "1010";
20
  beg := false;
21
 ELSE
22
23
 IF clk'EVENT AND clk = '1' THEN
24
25
  IF zaehl < 10000000 THEN
26
   zaehl := zaehl + 1;
27
   
28
  ELSE
29
--   intern <= NOT intern;  -- das hier funktioniert, es blinken alle 4                          LEDs
30
   intern <= intern(0) & intern(3 DOWNTO 1); --funktioniert nicht... why?
31
   zaehl := 0;
32
  END IF;
33
34
 END IF;
35
 END IF;
36
 END PROCESS p1;

von Mathi (Gast)


Lesenswert?

Du verwendest die Variable beg zum Initialisieren der Signale. Benutze 
doch lieber einen richtigen Reset.
Schau mal ob im Synthesebericht was mit dem Signal passiert ist.

von ITSE (Gast)


Lesenswert?

Hi,

danke für deine Antwort...

Meinst du es liegt an der Initialisierung mit meiner Variable "beg"? 
Kann sein, ich weiss aber nicht was du mit "verwende doch einen Reset" 
meinst. Kenne mich zwar ein bisschen mit VHDL aus, aber nicht mir 
FPGAs...

Ich nehme an, dass es eine bessere Methode für die Initialisierung des 
internen Signals "intern" gibt, das wirst du auch meinen.... aber wie?

Grüße

Bernd

von Mathi (Gast)


Lesenswert?

FPGAs haben einen externen Reset. Den führt man im Toplevel des Designs 
auf und weißt ihm den entsprechenden Pin zu.
Ein asynchroner Reset sieht dann so aus
1
process(reset_n, clk)
2
begin
3
  if(reset_n = '0')then
4
       --Signale initialisieren
5
  elsif(rising_edge(clk))then
6
      --signale verwenden
7
  end if;
8
end process;

Achte darauf das der Reset low_aktiv ist.

von ITSE (Gast)


Lesenswert?

DANKE, es funktioniert...

Noch eine Frage:

Ich benutze ja als externen Takt einen 16MHz Quarzoszillator. Deswegen 
hab ich den riesigen Zähler eingebaut um das Lauflicht/Blinklicht mit 
normalem Auge noch wahrzunehmen. Verbraucht dieser Zähler nicht sehr 
viele Hardware-Ressourcen im FPGA? Geht das nicht besser?

Kann ich evtl. eine der eingebauten PLLs benutzen anstatt den externen 
Takt? Ich weiss so gut wie nichts über die Lattice-PLLs...

Thx..

Bernd

von Mathi (Gast)


Lesenswert?

Mit den PPLs wird es bei 16MHz Eingangstakt nicht gehen. Die PPLs 
brauchen mindestens 25MHz.
Wenn Du die 25 hättest, weiß ich allerdings auch nicht ob man weit genug 
runterteilen könnte für einen so kleinen Takt.
Kannst Dir ja eine mit IPExpress generieren und mal schauen.
Aber der Zähler ist schon ne gängige Methode. Der Verbrauch ist nicht so 
hoch wie Du denkst. Ein 25 Bit breiter Zähler zählt bis 2^25-1. Das 
reicht für eine Frequenz von 0,5Hz. Und in einem modernen FPGA sind das 
nix.

Vg,
 Mathi

von Jan M. (mueschel)


Lesenswert?

Ripple-Carry-Zaehler wie in diesem Fall lassen sich sehr effizient 
aufbauen: Pro Bit braucht es genau eine LUT und ein FF.

PLLs bringen nicht viel, da diese eine gewisse Mindestfrequenz (meist 
ueber 1MHz) haben muessen.

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.