Forum: FPGA, VHDL & Co. Neustart - vhdl


von Fandango (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich hatte schon einmal damit begonnen, mein Elektronik Hobby auf 
programmierbare Logik zu erweitern.... einige Monate konnte ich jetzt 
aber so gut wie gar nichts in der Richtung machen und nun habe ich 
endlich die Zeit, noch einmal einen Anlauf zu beginnen.
Daher habe ich mir noch einmal den Klassiker des Hello World vorgenommen 
- die 7-Segment Anzeige. Dabei habe ich jetzt mal versucht z.B. ein 
component zu verwenden. Nicht weil es wohl nötig ist, sondern einfach um 
es zu üben.
Da ich keine Hardware besitze und nur Simulieren kann, hab ich als bcd 
Werte eine willkürliche rom Tabelle gemacht. Aber dennoch ist die Nibble 
Ausgabe versetzt - x"12" z.B.
Stelle 0 -> ansel "10" ist ok,
            nibble "0001" schon daneben das ist ja das hohe Nibble

2 Fragen habe ich aber und bitte um Unterstützung. (im code als 
Kommentar)
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
entity bcd_seg is
5
    Port ( data_in : in  STD_LOGIC_VECTOR(3 downto 0);
6
           anodes  : out STD_LOGIC_VECTOR (6 downto 0));
7
end bcd_seg;
8
9
architecture Behavioral of bcd_seg is
10
type MY_ROM is array (0 to 15) of STD_LOGIC_VECTOR(6 downto 0);
11
constant BCD_ROM : MY_ROM := ("0000000","0000001","0000010","0000100",
12
                     "0100000","0000001","0100010","0100100",
13
                     "1000000","1000001","0100010","0100100",
14
                     "1100000","1100001","1100010","1100100");
15
begin
16
  process (data_in) begin 
17
    anodes <= BCD_ROM(to_integer(unsigned(data_in)));
18
  end process;
19
20
end Behavioral;
21
22
23
24
library IEEE;
25
use IEEE.STD_LOGIC_1164.ALL;
26
use IEEE.NUMERIC_STD.ALL;
27
entity bcd_mux is
28
  Generic( NIBBLES : integer := 2;
29
        F_MUX   : integer := 10000000);
30
  Port( clk   : in  STD_LOGIC;
31
      data  : in  STD_LOGIC_VECTOR (NIBBLES*4-1 downto 0);
32
      ansel : out STD_LOGIC_VECTOR (NIBBLES-1 downto 0) := (others=>'0');
33
      anodes: out STD_LOGIC_VECTOR (6 downto 0) := (others=>'0'));
34
end bcd_mux;
35
36
architecture Behavioral of bcd_mux is
37
signal s_clkdiv : integer range 0 to 50000000/F_MUX := 0;
38
signal s_stelle : integer range 0 to NIBBLES-1 := 0;
39
signal s_nibble : STD_LOGIC_VECTOR(3 downto 0):="0000";
40
component bcd_seg
41
    Port (data_in : in  STD_LOGIC_VECTOR(3 downto 0);
42
           anodes  : out STD_LOGIC_VECTOR (6 downto 0));
43
end component;
44
begin
45
46
stellen_multiplexen : process begin
47
    wait until rising_edge(clk);
48
    if(s_clkdiv < 50000000/F_MUX) then
49
      s_clkdiv <= s_clkdiv + 1;
50
    else
51
      s_clkdiv <= 0;
52
    --Ich weiß, Signale nehmen ihren neuen Zustand erst am Ende des Prozesses an. Jedenfalls
53
    --habe ich das so aufgenommen, aber mehr als eine Phrase ist das irgendwie nicht für mich.
54
    --Ist das 
55
    --a) die Ursache dafür, daß ich die falschen Nibble zum ansel bekomme und
56
    --b) wie schreibe ich es richtig, wie verstehe ich meinen Fehler. Also nicht einfach durch passend machen der Offsets in den Vektor trial and error lässt mich ja beim nächsten mal wieder alt aussehen :-(
57
--die Testbench gibt x"12" und dann x"a1" aus.
58
59
      s_nibble <= data( (s_stelle*4+3) downto (s_stelle*4));  
60
      if(s_stelle < (NIBBLES-1)) then 
61
        s_stelle <= s_stelle + 1;
62
      else
63
        s_stelle <= 0;            
64
      end if;  
65
    end if;
66
  end process stellen_multiplexen;
67
  
68
die_anzeige: bcd_seg port map ( s_nibble, anodes );
69
  
70
stelle_auswählen:  process (s_stelle) begin
71
  --Für Anfänger wird immer gesagt, es sei alle Taktsynchron zu machen - 
72
  --betrifft das hier das multiplexen der Anzeigestellen auch???
73
  --s_stelle ändert sich doch nur im Takt oben.
74
  --und -sei das mal etwas gewichtigeres als eine Anzeige auszuwählen, also
75
  --ein umfangreicherer Prozess: pauschal am Anfang ein wait, oder wann nicht?
76
  --if(rising_edge(clk)) then
77
  ansel <= (others=>'1');
78
  ansel(s_stelle) <= '0';
79
  --end if;
80
  end process stelle_auswählen;
81
  
82
end Behavioral;

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


Lesenswert?

In diesem Prozess wird noch die "alte" s_stelle verwendet:
1
      s_nibble <= data( (s_stelle*4+3) downto (s_stelle*4));  
2
      if(s_stelle < (NIBBLES-1)) then 
3
        s_stelle <= s_stelle + 1;
4
      else
5
        s_stelle <= 0;            
6
      end if;
hier aber sofort die "neue"
1
  ansel(s_stelle) <= '0';
Das Problem heißt Latency, weil s_nibble quasi später kommt...

Es bringt jetzt aber rein gar nichts, den Prozess so umzubauen:
1
      if(s_stelle < (NIBBLES-1)) then 
2
        s_stelle <= s_stelle + 1;
3
      else
4
        s_stelle <= 0;            
5
      end if;  
6
      s_nibble <= data( (s_stelle*4+3) downto (s_stelle*4));
Weil auch in dieser letzten Zeile noch der alte Wert von s_stelle 
verwendet wird.
Das ist gemeint mit der Signalzuweisung erst am Edne des Prozesses. Alle 
Berechnungen mit Signalen verwenden den "alten" Signalwert und berechnen 
daraus einen "neuen" Wert, der dann am Ende dem Signal zugewiesen 
wird.
Du machst das hier doch auch so:
1
stelle_auswählen:  process (s_stelle) begin
2
  ansel <= (others=>'1');
3
  ansel(s_stelle) <= '0'; -- die letzte Zuweisung an ein Signal gewinnt
4
end process stelle_auswählen;

Zurück zu deinem Problem. Machs mal so:
1
:
2
      if(s_stelle < (NIBBLES-1)) then 
3
        s_stelle <= s_stelle + 1;
4
      else
5
        s_stelle <= 0;            
6
      end if;  
7
    end if;
8
  end process stellen_multiplexen;
9
10
  s_nibble <= data( (s_stelle*4+3) downto (s_stelle*4));  
11
12
stelle_auswählen:  process (s_stelle) begin
13
:

>  pauschal am Anfang ein wait,
Nein.
Ein wait until bringt dir zwingend Speicherelemente aka Fliflops ins 
Design. Und damit einen Takt Verzögerung aka. Latency auf das Signal...

> oder wann nicht?
Ein synchrones Design ist erst mal ein Design, das nur einen Takt hat, 
und bei dem externe signale einsynchronisiert sind. Ob da ein wait im 
Prozess auftaucht, bestimmt lediglich, ob ein Speicherelement nötig ist, 
oder nicht.

von Fandango (Gast)


Lesenswert?

Vielen Dank!
Ich glaube das hilft mir schon mal als Denkhilfe am Wochenende. Weitere 
Ideen ein langsameres Hirn auf Touren zu bringen sind mir natürlich sehr 
willkommen.

Ich lasse in Ruhe den Post sacken und wünsche erst mal ein schönes 
Wochenende.

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.