Forum: FPGA, VHDL & Co. [VHDL] Constant must have a value


von A. M. (am85)


Angehängte Dateien:

Lesenswert?

Meine Erfahrungen sind noch sehr jung in Sachen Xilinx, VHDL und 
Hardwaredesign. Nun möchte ich aber einen einfachen Paritätsgenerator in 
Form eines IP Cores in mein EDK Design einbinden und den aus einer C 
Anwendung heraus über ein paar vorher per IP Wizard definierten Register 
steuern. Beim Synthetisieren des Designs gibt er mir aber folgende 
Fehlermeldung aus:

ERROR:Xst:774 - ".../pargen_core_v1_00_a/hdl/vhdl/user_logic.vhd" line 
157: Constant must have a value : 'a'.

In Zeile 157 wird die variable "result" deklariert:
1
function reverseVector (a: in std_logic_vector) return std_logic_vector is
2
    variable result: std_logic_vector(a'reverse_range);
3
begin
4
  for i in a'range loop
5
    result((a'length-1)-i) := a(i);
6
  end loop;
7
  return result;
8
end;

Um sicher zu gehen, ob der Fehler nicht eigentlich an einer ganz anderen 
Stelle entsteht, habe ich einmal die ganze VHDL Datei angehängt.

Danke schon einmal

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


Lesenswert?

Zum Synthesezeitpunkt ist in der Zeile nach:
1
function reverseVector (a: in std_logic_vector) return std_logic_vector is
noch nicht bekannt, welche Breite a beim Aufruf haben wird:
1
    variable result: std_logic_vector(a'reverse_range);
Woher hast du diese Funktion?


Dieser Prozess hier ist sinnlos:
1
  GENERATOR: process(reg_in) 
2
    variable p : std_logic;
3
  begin
4
  reg_status <= (others => '1'); -- set busy  --- !!! passiert gleichzeitig
5
   
6
  p := reg_in(0);
7
  for i in 1 to 7 loop
8
    p := p xor reg_in(i);
9
  end loop;
10
  
11
  if reg_conf = "11110000" then
12
    reg_out <= not p;
13
  else
14
    reg_out <= p;
15
  end if; 
16
17
  reg_status <= (others => '0'); -- set ready  --- !!! passiert gleichzeitig, aber die letzte Zuweisung gewinnt  :-o
18
  end process GENERATOR;
Denn der Prozess wird nicht einfach von oben nach unten abgearbeitet 
(wir sind ja nicht in C oder Assembler oder sonst einer 
Programmiersprache), sondern die Operationen innerhalb des Prozesses 
passieren GLEICHZEITIG. D.h. in einem Prozess gewinnt immer die letzte 
Zuweisung an ein Signal. Und das ist die hier:
1
  reg_status <= (others => '0'); -- set ready
reg_status wird niemals etwas anderes sein als x"00"    :-o


Du hast noch sehr grundlegende Probleme zum Verständnis der 
Hardwarebeschreibung mit VHDL. Besorg dir das Buch VHDL-Synthese von 
Reichardt&Schwarz und lies das mal durch...

von A. M. (am85)


Lesenswert?

Lothar Miller schrieb:
> Woher hast du diese Funktion?

Hier her: http://www.labbookpages.co.uk/fpgas/edkHowTos/peripherals.html
Genauer unter Punkt "Writing the Peripheral VHDL"

Lothar Miller schrieb:
> Denn der Prozess wird nicht einfach von oben nach unten abgearbeitet
> (wir sind ja nicht in C oder Assembler oder sonst einer
> Programmiersprache), sondern die Operationen innerhalb des Prozesses
> passieren GLEICHZEITIG.

Mh, meine aktivere VHDL Zeit ist schon ein paar Semester her, aber mir 
hängt noch im Hinterkopf, dass in einem Prozess eben nicht alles 
parallel abgearbeitet wird, sondern Schritt für Schritt. Dazu ein Zitat 
aus Herrn Reichardts "Lehrbuch Digitaltechnik":

>4. Im Ausführungsteil von Prozessen [...] sind nur unbedingte >Signalzuweisungen 
und spezielle sequenzielle Anweisungen erlaubt. Diese >Anweisungen werden strikt 
nacheinander ausgeführt.[...].

Entweder widerspricht das deiner Aussage, oder meine Interpretation ist 
nicht ganz korrekt. Ich lasse mich da gerne eines besseren belehren.

Mit der Gültigkeit der letzten Signalzusweisung hast du allerding Recht 
und das.

Lothar Miller schrieb:
> Du hast noch sehr grundlegende Probleme zum Verständnis der
> Hardwarebeschreibung mit VHDL. Besorg dir das Buch VHDL-Synthese von
> Reichardt&Schwarz und lies das mal durch...

Ich würde eher sagen, dass meine letzte Vorlesung bei Herrn Reichardt zu 
lange her ist ;-)

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


Lesenswert?

> Entweder widerspricht das deiner Aussage, oder meine Interpretation ist
> nicht ganz korrekt. Ich lasse mich da gerne eines besseren belehren.
Sie werden sequentiell abgearbeitet, aber zwischen den einzelnen 
Schritten vergeht keine Zeit! Es gibt innerhalb des Prozesses zware 
Ablaufbegriffe wie Vorher und Hinterher, aber keinerler Zeitbegriffe wie 
Früher, Jetzt und Später. Wie gesagt: die letzte Signalzuweisung 
gewinnt.

von A. M. (am85)


Lesenswert?

Lothar Miller schrieb:
> Sie werden sequentiell abgearbeitet, aber zwischen den einzelnen
> Schritten vergeht keine Zeit! Es gibt also keine Zeitbegriffe wie
> Vorher, Jetzt und Später. Wie gesagt: die letzte Signalzuweisung
> gewinnt.

Gut, aus meinem Code ist ja aber schonmal zu erkennen, wie das ganze 
ablaufen soll. Wie könnte man sowas denn sinnvoll in VHDL realisieren?

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


Lesenswert?

> Wie könnte man sowas denn sinnvoll in VHDL realisieren?
In dem speziellen Fall oben brauchst du kein Busy-Flag, weil der Prozess 
sowieso in einer theoretischen Zeit 0 abgearbeitet wird. In der Praxis 
hast du natürlich eine Laufzeit, die dir die maximale Taktfrequenz des 
Designs reduzieren wird.

>>>> gibt er mir aber folgende Fehlermeldung aus: ...
Sieh dir das Original mal genau an:
Bus2IP_Data  : std_logic_vector(0 to C_DWIDTH-1);  -- 32 Bits
data_BUS2IP  : std_logic_vector(31 downto 0);      -- 32 Bits
data_BUS2IP  <= reverseVector(Bus2IP_Data);
Und dann dein Code:
slv_reg0        : std_logic_vector(0 to C_SLV_DWIDTH-1); -- 32 Bits
reg_in          : std_logic_vector(7 to 0);              -- 8 Bits
reg_in           <= reverseVector(slv_reg0);
Fällt dir was auf?  :-o

von A. M. (am85)


Lesenswert?

Lothar Miller schrieb:
> Fällt dir was auf?  :-o

Ich bin mal ganz naiv davon ausgegangen, dass nur die 8 Bits, die mich 
auch wirklich interessieren in den Vektor übertragen werden und der Rest 
im Nirvana verschwindet.

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


Lesenswert?

> Ich bin mal ganz naiv davon ausgegangen
Das wird der Synthesizer ein wenig anders sehen... :-o
Probiers mal so:
reg_in           <= reverseVector(slv_reg0(o to 7));

von A. M. (am85)


Lesenswert?

Lothar Miller schrieb:
> Probiers mal so:
> reg_in           <= reverseVector(slv_reg0(o to 7));

Das macht schon viel mehr Sinn. Ich werds mal ausprobieren.

von A. M. (am85)


Lesenswert?

Mh, ich bekomme leider immer noch die gleiche Fehlermeldung. Prinzipiell 
sollte die Funktion ja aber funktionieren.

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.