mikrocontroller.net

Forum: FPGA, VHDL & Co. Port Zuweisung


Autor: vlaad (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zeig mal deinen Code. Sonst wird das nichts...

Autor: vlaad (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal,
wie gewünscht der Code zur Klärung:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity freqdiv is         
--generic (sw : unsigned(7 downto 0) := "00000011");

port (
      clk : in std_logic;
      sw1 : in unsigned(7 downto 0);
      cout: out std_logic
     );
end freqdiv;

architecture freqdiv_arch of freqdiv is

signal p_takt : bit :='0';
signal sw : unsigned(0 to 7) :=sw1;
signal posCount: integer range 0 to ((to_integer(sw))-1):= 0;

begin

process (clk)

--variable posCount: integer range 0 to ((to_integer(sw))-1):= 0;

begin
--- hab es hier etwas gekürzt, sonst wird der Eintrag ja noch länger
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity freqdiv is         
port (
      clk : in std_logic;
      sw1 : in unsigned(7 downto 0);
      cout: out std_logic
     );
end freqdiv;

architecture freqdiv_arch of freqdiv is

signal p_takt : bit :='0';
signal posCount: integer range 0 to 255 := 0;
signal endCount: integer range 0 to 255 := 0;

begin

process (clk)
  endCount <= to_integer(unsigned(sw1));
begin
  if rising_edge(clk) then
   : 
    if pos_Count=endCount then
    :
       posCount <= 0;
    else
       posCount <= posCount+1;
    end if;
  end if;
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.

Autor: vlaad (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity CountInt is
    Port ( clk : in  STD_LOGIC;
           cnt : out  STD_LOGIC_VECTOR (3 downto 0));
end CountInt;

architecture Behavioral of CountInt is
signal counter : integer range 0 to 9 := 0;  -- für Zähler von 0 bis 9
begin
   process begin
      wait until rising_edge(clk);
      counter <= counter+1; 
   end process;
   cnt     <= std_logic_vector(to_unsigned(counter,4));
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:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity CountInt is
    Port ( clk : in  STD_LOGIC;
           cnt : out  STD_LOGIC_VECTOR (3 downto 0));
end CountInt;

architecture Behavioral of CountInt is
signal counter : integer range 0 to 9 := 0;
begin
   process begin
      wait until rising_edge(clk);
      if counter<9 then      counter <= counter+1; 
      else                   counter <= 0;
      end if;
   end process;
   cnt     <= std_logic_vector(to_unsigned(counter,4));
end Behavioral;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

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

Autor: vlaad (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.