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
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
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.
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.
> 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; |
Da ging was mit dem Anhang schief... :-/ Hier das Bild vom richtig implementierten 0..9 Zähler.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.