Forum: FPGA, VHDL & Co. Port Zuweisung


von vlaad (Gast)


Lesenswert?

Hallo Leute,
ich brauch echt mal eure Hilfe. Bin noch relativ neu bei VHDL und doch 
schon am verzweifeln.
Ich habe einen Frequenzteiler programmiert bei dem der Teiler dynamisch 
gesetzt werden muß. Soll heißen, ich habe einen CPDL bei dem über 8 
Leitungen mit hilfe eines Schiebeschalters der Teiler gesetzt wird. 
Soviel zur Hardware, nun habe ich einfach einen Frequenzteiler 
geschrieben, bei dem ich zum Testen ein generic in der Entity gesetzt 
habe und dem einen festen Wert zugewiesen habe. Das Resultat, der 
Frequenzteiler läuft soweit. Nun kommt der Schritt bei dem ich hänge. 
Ich muß nun ja die Ports für die Leitungen setzen und das klappt nicht. 
Ich hatte gedacht ich setze die Leitungen einfach als Vector an und lese 
den im Verlauf einfach aus, aber das klappt nicht. Ich habe es mit einem 
std_logic_vector und einem unsigned versucht. Mit der festen Definition 
im generic klappt es auch immer und das obwohl ich tlw zum integer 
wandel, wenn ich aber über port gehen will bekomme ich die 
unterschiedlichsten Fehlermeldungen. Tlw darf ich dann nicht zum Integer 
wandeln, tlw will er einen konstanten Teiler, tlw will er den 
verwendeten Bereich nicht hinnehmen usw.
Ich tippe echt darauf, dass ich komplett den falschen Ansatz habe. Könnt 
Ihr mir vielleicht mal einen Tip geben wie man da generell rangehen muß. 
Es muß doch gehen einen Port dynamisch zu halten und nicht immer fest 
definierte Bereiche zu setzen.
Danke schon mal
vlaad

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


Lesenswert?

Zeig mal deinen Code. Sonst wird das nichts...

von vlaad (Gast)


Lesenswert?

Hallo nochmal,
wie gewünscht der Code zur Klärung:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity freqdiv is         
6
--generic (sw : unsigned(7 downto 0) := "00000011");
7
8
port (
9
      clk : in std_logic;
10
      sw1 : in unsigned(7 downto 0);
11
      cout: out std_logic
12
     );
13
end freqdiv;
14
15
architecture freqdiv_arch of freqdiv is
16
17
signal p_takt : bit :='0';
18
signal sw : unsigned(0 to 7) :=sw1;
19
signal posCount: integer range 0 to ((to_integer(sw))-1):= 0;
20
21
begin
22
23
process (clk)
24
25
--variable posCount: integer range 0 to ((to_integer(sw))-1):= 0;
26
27
begin
28
--- hab es hier etwas gekürzt, sonst wird der Eintrag ja noch länger
29
end freqdiv_arch;

Bei dieser Version bekomme ich die Fehlermeldung:
"Couldn't find binding for variable sw1" und es macht auch keinen 
Unterschied ob ich nun direkt den Port verwenden will, oder ob ich wie 
hier ein temporäres Signal weiter verarbeiten will und zwischen Variable 
und Signal gibt es auch keinen Unterschied.
Ich hoffe das macht mein Problem etwas klarer.
Danke nochmal
vlaad

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


Lesenswert?

Das geht nicht:
> signal sw : unsigned(0 to 7) :=sw1;
Woher soll denn der Synthesizer zur Übersetzugnszeit wissen, welchen 
Pegel du später beim Einschalten an den Pins hast?

Und damit geht logischerweise auch das nicht:
> signal posCount: integer range 0 to ((to_integer(sw))-1):= 0;

Übrigens:
> signal sw : unsigned(0 to 7) := sw1;
Das ist böse, böse, böse...
Du drehst damit die Bitreihenfolge um!!!  :-o
sw(3) ist damit gleich sw1(4), sw(0) = sw1(7), usw...
Das sollte man nur machen, wenn man ganz genau weiß, was man da tut.


Du wirst es etwa so machen müssen:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity freqdiv is         
6
port (
7
      clk : in std_logic;
8
      sw1 : in unsigned(7 downto 0);
9
      cout: out std_logic
10
     );
11
end freqdiv;
12
13
architecture freqdiv_arch of freqdiv is
14
15
signal p_takt : bit :='0';
16
signal posCount: integer range 0 to 255 := 0;
17
signal endCount: integer range 0 to 255 := 0;
18
19
begin
20
21
process (clk)
22
  endCount <= to_integer(unsigned(sw1));
23
begin
24
  if rising_edge(clk) then
25
   : 
26
    if pos_Count=endCount then
27
    :
28
       posCount <= 0;
29
    else
30
       posCount <= posCount+1;
31
    end if;
32
  end if;
33
end freqdiv_arch;

Du darfst übrigens nicht davon ausgehen, dass ein Zähler, den du als
> signal posCount: integer range 0 to 47;
definierst, in der Hardware auch wirklich nur von 0 bis 47 zählt. Der 
wird logischerweise 6 Bit breit sein müssen, und daher erst bei 63 
überlaufen.

von vlaad (Gast)


Lesenswert?

Moin,
dank deiner Hilfe ist der Compiler nun endlich zufrieden. Echt ein 
dummer Fehler gewesen.

Lothar Miller schrieb:
>> signal sw : unsigned(0 to 7) := sw1;
> Das ist böse, böse, böse...
> Du drehst damit die Bitreihenfolge um!!!  :-o
> sw(3) ist damit gleich sw1(4), sw(0) = sw1(7), usw...
> Das sollte man nur machen, wenn man ganz genau weiß, was man da tut.

Das war auch gar nicht so gemeint gewesen. Habe es nur einfach nicht 
gesehen und wenn man da alleine vorsitzt, dann gibt auch keiner einen 
Stoß in die Rippen ;-)

Lothar Miller schrieb:
> Du darfst übrigens nicht davon ausgehen, dass ein Zähler, den du als
>> signal posCount: integer range 0 to 47;
> definierst, in der Hardware auch wirklich nur von 0 bis 47 zählt. Der
> wird logischerweise 6 Bit breit sein müssen, und daher erst bei 63
> überlaufen.

Wie meinst du das? Soll das heißen, ich kann generell nur bestimmte 
Werte verwenden, oder meinst du der Integer ist die falsche Wahl. Die 
Simulation funktioniert aber einwandfrei.

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


Angehängte Dateien:

Lesenswert?

> Wie meinst du das? Soll das heißen, ich kann generell nur bestimmte
> Werte verwenden, oder meinst du der Integer ist die falsche Wahl.
Nein, ein Integer ist für Zähler optimal, weil Vergleiche auf diesen 
Zähler in VHDL einfach zu schreiben und zu lesen sind.

> Die Simulation funktioniert aber einwandfrei.
Die wird dir sogar eine Wertebereichsverletzung melden.
Die Hardware aber nicht...

Mal angenommen wir wollen einen Zähler von 0 bis 9 bauen. Und wir 
wissen, dass z.B. ein 4-Bitzähler am Ende ganz einfach wieder bei 0 
beginnt, dann könnten wir den logischen Kurzschluss begehen und sowas 
beschreiben:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity CountInt is
6
    Port ( clk : in  STD_LOGIC;
7
           cnt : out  STD_LOGIC_VECTOR (3 downto 0));
8
end CountInt;
9
10
architecture Behavioral of CountInt is
11
signal counter : integer range 0 to 9 := 0;  -- für Zähler von 0 bis 9
12
begin
13
   process begin
14
      wait until rising_edge(clk);
15
      counter <= counter+1; 
16
   end process;
17
   cnt     <= std_logic_vector(to_unsigned(counter,4));
18
end Behavioral;
Die Synthese braucht für diesen Zähler (10 Zustände) 4 Bit. Es wird also 
ein 4-Bit-Counter implementiert. Der läuft auch über. Aber nicht von 9 
auf 0, sondern von 15 auf 0. Der counter zählt also in der Realität 
von 0 bis 15!!! Das wird uns von der Synthese nicht gesagt. In der 
Simulation gibt es zum Glück aber einen Fehler, denn 9+1=10, und 10 sind 
nicht mehr im definierten Range.

So wird das korrekt implementiert:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity CountInt is
6
    Port ( clk : in  STD_LOGIC;
7
           cnt : out  STD_LOGIC_VECTOR (3 downto 0));
8
end CountInt;
9
10
architecture Behavioral of CountInt is
11
signal counter : integer range 0 to 9 := 0;
12
begin
13
   process begin
14
      wait until rising_edge(clk);
15
      if counter<9 then      counter <= counter+1; 
16
      else                   counter <= 0;
17
      end if;
18
   end process;
19
   cnt     <= std_logic_vector(to_unsigned(counter,4));
20
end Behavioral;

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


Angehängte Dateien:

Lesenswert?

Da ging was mit dem Anhang schief... :-/
Hier das Bild vom richtig implementierten 0..9 Zähler.

von vlaad (Gast)


Lesenswert?

Lothar Miller schrieb:
> Der läuft auch über. Aber nicht von 9
> auf 0, sondern von 15 auf 0. Der counter zählt also in der Realität
> von 0 bis 15!!!

Ach so, das meintest du. Nee, Nee, ich setze auf 0, wenn ich das Ziel 
erreicht habe.
Nun muß ich warten bis die Platine fertig ist und dann sehe ich ja, ob 
alles so klappt wie ich mir das vorgestellt habe, oder ob ich noch was 
übersehen habe ;-)

Danke nochmal für deine Hilfe, echt klasse von dir

vlaad

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.