Forum: FPGA, VHDL & Co. VHDL - noch so ein anfänger


von Ben (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,

ich lese ja schon seit langer Zeit immer wieder gerne hier die 
Forumsbeiträge - heute ist es soweit, ich komme nicht weiter und wende 
mich auch mal an die nette Community hier.

Also erstmal(möglcihst) kurz und knapp die Situation:
Ich habe schon seit einiger zeit Programmiererfahrung mit Pic & co. und 
dachte mir: eine neue Herausforderung: Beschreibe die Hardware anstatt 
sie zu Programieren. Gesagt - Getan.. sein ein paar wochen versuche mich 
an einem Altera FPGA(cyclone I). Die ersten Versuche liefen auch alle 
super(counter, blinkende LEDs, 7Segmentanzeigen, etc).. Nun, mein 
testboard hat auch einen kleinen Lautsprecher. Also dachte ich mir, 2 
Eingänge für Frequenz + und -, einem single port ram + init wert und ein 
ausgang..

Im Anhang dazu eine kleine Skizze....

Nunja, in der Simulation gehen die einzelkomponenten alle, einige habe 
ich aus vorherigen Projekten übernommen(laufen also auch in der Praxis), 
aber die gesamtschaltung geht natürlich nicht.

Ich vermute mal, das der fehler irgendwo im bereich des signals/ausgangs 
"WREN" liegt(zu kurz??), aber das überlasse ich mal den Profis.
So .. ich hoffe, ich habe nichts vergessen..
Hier Dann mal der VHDL code:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
6
entity controler is
7
port(
8
    --INPUT
9
    plus, minus: in std_logic;  --Entprellte Eingangsignale Plusrechnen/Minusrechnen
10
    act_data: in std_logic_vector(23 downto 0); -- Aktuellen wert am RAM-ausgang einlesen ram-initwert DEZ 2500000
11
    clock: in bit; --50MHZ sync mit ram-takt
12
    --OUTPUT
13
    new_data : out std_logic_vector(23 downto 0); --zu data in von RAM
14
    wren : out std_logic := '0';  --wren von ram
15
    adress: out std_logic := '0' --RAM adresse
16
    );
17
End;
18
19
20
architecture verhalten of controler is 
21
  signal s_wren: std_logic:='0';
22
  signal s_data: unsigned(23 downto 0);
23
  signal s_plus, s_minus, s_out_p, s_out_m, s_pp, s_pm: std_logic:= '0';
24
Begin
25
  
26
  
27
  pegel_leser:process(clock)
28
  begin
29
    If (clock'event and clock = '1' ) then
30
      If (plus = '0') then
31
        ---plus gedrückt
32
        s_plus <= '1';
33
      Elsif (minus = '0') then
34
        ---minus gedrückt
35
        s_minus <= '1';
36
      Else
37
        -- nichts gedrückt
38
        s_plus <= '0';
39
        s_minus <= '0';
40
      End if;  
41
      --D-FF + flankenerkennung
42
      s_out_p <= s_plus;
43
      s_out_m <= s_minus;    
44
      s_pp <= s_plus and not s_out_p;
45
      s_pm <= s_minus and not s_out_m;
46
    End if;
47
  
48
  End process;
49
  
50
  
51
  rechner: process(s_pp, s_pm, act_data)
52
  Begin
53
    -- wenn flanke an plus oder minus
54
    -- setze wren und errechne aktuellen neuen wert um frequenz um 10 hz zu erhöhen/abzusenken
55
    If s_pp = '1' then
56
      s_wren <= '1';
57
      s_data <= 50000000 / ((50000000 / unsigned(act_data)) + 10);
58
    Elsif s_pm = '1' then
59
      s_wren <= '1';
60
      s_data <= 50000000 / ((50000000 / unsigned(act_data)) - 10);
61
    Else
62
      s_wren <= '0';
63
      s_data <= to_unsigned(0, 24);
64
    End if;
65
    
66
  End Process;
67
    
68
  adress <= '0';
69
  wren <= s_wren;
70
  new_data <= std_logic_vector(unsigned(s_data));
71
72
End;

So dann Vielen Dank schon mal für eure Hilfe!

Gruß
Ben

von Tim P. (Firma: Student) (t8p1)


Lesenswert?

Hi Ben,
1
pegel_leser:process(clock)
Müsste die sensitive list nicht auch auf minus und plus reagieren?
1
s_out_p <= s_plus;
2
s_out_m <= s_minus;    
3
s_pp <= s_plus and not s_out_p;
4
s_pm <= s_minus and not s_out_m;

Soll sich hier s_pp aus dem s_out_p aus der zweiten Zeile darüber geben? 
Hier dürftest du ein Problem Timing Problem erhalten. Des Weiteren ist 
es wirklich gewünscht nur zwei kombinatorischen Teile ohne sequentiellen 
Block zu verwenden? Aus Erfahrung ist es auch nicht wirklich schlau 
Ausgänge über Latches zu betreiben, in diesem Fall direkt den Ausgang 
über ein Signal zu treiben. Ich würde den Ausgang eher über ein Register 
treiben.

In der Simulation solltest du dir auch die Timings zwischen pegel_leser 
und rechner genauer anschauen, da pegel_leser auf jede Taktflange 
reagiert ist s_plus und s_minus gleich wieder null.

Grüße,
Tim

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


Lesenswert?

Ben schrieb:
> pegel_leser:process(clock) ...
Mit diesem komplizierten "Einleseprozess" machst du zwar so was 
ähnliches wie eine Synchronisierungsstufe, aber da sind zu viele 
Abhängigkeitrm drin, und deshalb passiert dort (früher oder später) das:
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html

Es hilft hier übrigens gar nichts, dass die Taster schon entprellt 
sind...


Tim P. schrieb:
> Müsste die sensitive list nicht auch auf minus und plus reagieren?
Nein. Der Prozess ist nur vom Takt abhängig.

: Bearbeitet durch Moderator
von FPGA-Ingenieur (Gast)


Lesenswert?

>s_data <= 50000000 / ((50000000 / unsigned(act_data)) + 10);
was oll dieser Konstrukt bewirken?

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


Lesenswert?

Tim P. schrieb:
> Soll sich hier s_pp aus dem s_out_p aus der zweiten Zeile darüber geben?
> Hier dürftest du ein Problem Timing Problem erhalten.
Wieder nein.
Jedes der Signale dort ist getaktet und damit ein Flipflop. Mithin ist 
das insgesamt nur eine weitere Sync-Stufe für die Flankenerkennung.

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


Lesenswert?

Ben schrieb:
> Ich vermute mal, das der fehler irgendwo im bereich des signals/ausgangs
> "WREN" liegt
Welcher "Fehler" denn? Wie äussert der sich? Und was hättest du 
stattdessen erwartet?

: Bearbeitet durch Moderator
von Ben (Gast)


Lesenswert?

Hallo zusammen,

danke für eure antworten. Also...

Tim P. schrieb:
> Ich würde den Ausgang eher über ein Register
> treiben.

Ich denke mal, einiges hat schon Lothar beantwortet, aber dein vorschlag 
mit dem Register werde ich mal versuchen.

Lothar M. schrieb:
> Mit diesem komplizierten "Einleseprozess" machst du zwar so was
> ähnliches wie eine Synchronisierungsstufe, aber da sind zu viele
> Abhängigkeitrm drin, und deshalb passiert dort (früher oder später) das:
> 
http://www.lothar-miller.de/s9y/archives/64-State-Machine-mit-asynchronem-Eingang.html
>
> Es hilft hier übrigens gar nichts, dass die Taster schon entprellt
> sind...

Wie bekomme ich den Einleseprozess denn besser hin - zumal die 
angschlossenen taster ja nur bei der ersten Taktflanke verarbeitet 
werden sollen.?

FPGA-Ingenieur schrieb im Beitrag #4333654:
>>s_data <= 50000000 / ((50000000 / unsigned(act_data)) + 10);
> was oll dieser Konstrukt bewirken?

Dieses Konstruckt soll(jedenfalls in der Theorie...) mir den 
vergleichswert errechen. Also an meinem "Soundausgang" soll eine 
frequenz anliegen. Dies realisiere ich mit einem counter, der bis X 
hochzählt(je nachchdem welche frequenz am ausgang gewunscht ist, 
erreichne ich mit diesem code den gewünschten vergleichswert, bis zu dem 
der couter zählt. Ist dieser vergleichswert erreicht, wird das 
asugangssignal getoggelt und der counter auf 0 gesetzt.

Lothar M. schrieb:
> Welcher "Fehler" denn? Wie äussert der sich? Und was hättest du
> stattdessen erwartet?

Also der Fehler.. ich bekomme keinerlei ausgangssignal am 
"soundausgang".
Wenn ich meinen counter am ausgang zu einem festgeschriebenen festen 
wert zählen lasse, funktioniert dieser. Mit dem controler und ram nicht. 
Von daher denke ich, das ich den Ram nicht beschrieben bekomme, so das 
mein counter sich durchgehend zurück setzt.
Hier nochmal der volständigkeit halber der code, der mit dem 
vergleichswert arbeitet(bzw arbeiten soll..)
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity megaDIV_variabel is
6
  Port ( 
7
  -- INPUT
8
      clock: in bit;    --Clock in 50MHZ
9
      vergleich: in std_logic_vector(23 downto 0); -- Vergleichswert vom RAM
10
  -- OUTPUT
11
      clock_out: out bit -- anschluss zum "Lautsprecher"
12
      );
13
end megaDIV_variabel;
14
15
architecture verhalten of megaDIV_variabel is
16
  signal s_vergleich: unsigned (23 downto 0);
17
  signal s_counter: unsigned (23 downto 0):=x"000000";
18
  signal s_toggle: bit:='0';
19
  
20
Begin
21
  frequenzcounter: process(clock)
22
  Begin
23
    IF (clock'event and clock = '1') then
24
      --Wenn zählwert größer ist als vergleichswert vom RAM -> Reset und ausgang toggeln
25
      If ( s_counter > s_vergleich) then
26
        s_counter <= x"000000";
27
        s_toggle <= not s_toggle;
28
      Else
29
        -- Sonst zähler +1
30
        s_counter <= s_counter + 1;
31
      End if;
32
    End if;  
33
  End Process;
34
  
35
  s_vergleich <= unsigned(vergleich);
36
  clock_out <= s_toggle;
37
  
38
End verhalten;

Viele Grüße
Ben

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.