Forum: FPGA, VHDL & Co. Typenkonvertierung in VHDL


von Andre B. (aaaaa)


Lesenswert?

Hallo,

ich habe ein Problem mit einer Typenkonvertierung in VHDL in meinem 
Xilinx Projekt:

Signaldefinitionen
type  old_variables_type is array (0 to 1023) of std_logic_vector (31 
downto 0);
signal old_variables :old_variables_type;
signal combined_data_1: std_logic_vector(31 downto 0);
signal aDCI_1: std_logic_vector (9 downto 0);

Im process gibt's dann folgende Abfrage

if old_variables(aDCI_1)(31 downto 16) + 1 = combined_data_1(31 downto 
16)

Error Message aus dem Synthesizer:

to_integer can not have such operands in this context.

Ähnliche Meldungen kommen auch bei to_unsigned () oder integer()
Es bringt auch nichts, statt "is_array (0 to 1023)" einfach "is array(9 
downto 0) zu schreiben.

Das kann doch nicht an einer Typenkonvertierung scheitern!

Könnt ihr mir helfen.

Beste Grüße

Andre

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


Lesenswert?

Andre B. schrieb:
> to_integer can not have such operands in this context.
In welchem Kontext?
Der von dir gepostete Ausschnitt verwendet to_integer gar nicht...

> Das kann doch nicht an einer Typenkonvertierung scheitern!
Welche Libs verwendest du?

von Andre B. (aaaaa)


Lesenswert?

Hallo,

ups sry, falsche Zeile kopiert: Ich poste mal die ersten 2 
Fehlermeldungen, die das Programm ausgibt, bei folgenden 
aufeinanderfolgenden Zeilen:

if old_variables(to_integer(aDCI_0)) = combined_data_0  then
  dina_0(31 downto 16) <= old_variables (aDCI_0)(31 downto 16);



Error Message: to_integer can not have such operands in this context.
Error Message: Wrong index type for old_variables.

Danke

Andre

von Andre B. (aaaaa)


Lesenswert?

Meine Bibs:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
--use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


-- Xilinx standard libary for Xilinx componet
library UNISIM;
use UNISIM.VComponents.all;

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


Lesenswert?

Andre B. schrieb:
> use IEEE.STD_LOGIC_UNSIGNED.ALL
Die std_logic_arith ist unnötig! Und weil die std_logic_arith 
unnötig ist, ist auch die std_logic_unsigned unnötig...

> if old_variables(to_integer(aDCI_0)) = combined_data_0  then
>  dina_0(31 downto 16) <= old_variables (aDCI_0)(31 downto 16);
Du haust dem Synthesizer da mit Zuweisungen und Indizierungen einiges an 
inkompatiblen Typen um die Ohren... :-o

Sieh dir mal das an, dann wird dir klar, wie du von A nach B kommst:
http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html

von Andre B. (aaaaa)


Lesenswert?

Hey Danke.

Spitzenmäßige Antwort. Die ersten 2 Zeilen sind schon mal fehlerfrei:

if old_variables(to_integer(unsigned(aDCI_0)))(31 downto 16) = 
combined_data_0(31 downto 16)  then

und

dina_0(31 downto 16) <= old_variables (to_integer(unsigned(aDCI_0)))(31 
downto 16);

Grüße

André

von Duke Scarring (Gast)


Lesenswert?

Andre B. schrieb:
> -- Xilinx standard libary for Xilinx componet
> library UNISIM;
> use UNISIM.VComponents.all;
Auf die Bibliothek kann man im Allgemeinen auch verzichten. Die ist 
wahrscheinlich auf Anweisung vom Marketing in das Template gekommen...

Duke

von Andre B. (aaaaa)


Lesenswert?

Duke Scarring schrieb:
> Andre B. schrieb:
>> -- Xilinx standard libary for Xilinx componet
>> library UNISIM;
>> use UNISIM.VComponents.all;
> Auf die Bibliothek kann man im Allgemeinen auch verzichten. Die ist
> wahrscheinlich auf Anweisung vom Marketing in das Template gekommen...


Hallo Duke,

die kommt nicht aus dem Marketing. Die benötigt das Programm doch für 
RAM-Bausteine, PLL etc. Oder wird das in der ISE im Hintergrund immer 
automatisch mit eingebunden. Aber selbst dann würde ich es, rein der 
Vollständigkeit halber, drin lassen.

Grüße

Andre

von Duke Scarring (Gast)


Lesenswert?

Andre B. schrieb:
> Die benötigt das Programm doch für
> RAM-Bausteine, PLL etc.
Ja.
Aber RAMs beschreibe allgemeingültig und PLL (bzw. DCM) und Buffer 
kommen nur in der obersten Hierarchieebene (top-level) zum Einsatz.

Und selbst da hole ich mir nur die Elemente ins Design, die ich 
benötige. Das erhöht m.E. die Übersichtlichkeit:
1
library unisim;
2
use unisim.vcomponents.bufg;
3
use unisim.vcomponents.bufgmux;
4
use unisim.vcomponents.dcm_clkgen;
5
use unisim.vcomponents.iddr2;
6
use unisim.vcomponents.ibufds;
7
use unisim.vcomponents.ibufg;
8
use unisim.vcomponents.ibufgds_diff_out;

> Oder wird das in der ISE im Hintergrund immer
> automatisch mit eingebunden.
Nein.

> Aber selbst dann würde ich es, rein der
> Vollständigkeit halber, drin lassen.
Ich finde es für Anfänger/Einsteiger unübersichtlich bzw. unverständlich 
die Bibliothek defaultmäßig mit reinzunehmen.
Alle einfachen Sachen (LED, Taster, Schieberegister, SPI) lassen sich 
auch ohne die herstellerspeziefische UNISIM machen.

Duke

von W.S. (Gast)


Lesenswert?

Duke Scarring schrieb:
> Die ist
> wahrscheinlich auf Anweisung vom Marketing in das Template gekommen...

ähem.. bei mir liest sich der Kommentar von Xilinx ein bissel anders. Da 
steht nämlich, wenn man einige der xilinx-spezifischen vordeklarierten 
Bauteile benutzt, genau dann soll man diese Lib's mit einbinden. Sonst 
braucht man das nicht.

Aber mal abgesehen davon ärgert mich VHDL von Grund auf. Strenge 
Typprüfungen mögen ja nett gedacht sein, aber wie immer: "Gut gemeint 
ist das Gegenteil von gut gemacht". Genau deshalb hat man beim Bauen mit 
CPLD's und FPGA's den meisten Streß mit dem Kämpfen gegen die 
Programmiersprache. Warum kann man nicht einen Integertypen einfach 
deklarieren und dann benutzen ohne sich mit Konvertierungen und so 
unsinnigen "Fehlern" wie "diese Operation ist auf diesen Typ nicht 
anwendbar" herumzuschlagen? Ein OTTOKAR: integer(7 downto 0) ist 
sowohl eine Zahl als auch ein Bitvektor, verdammt nochmal! Bei jedem 
integer gibt es zwangsweise ein Bit mit dem Wert 2^0 und wenn er 7 
downto 0 deklariert ist, dann gibt es auch 2^1 bis 2^7, weswegen man 
sehr wohl auf OTTOKAR(5) zugreifen können müßte als auch damit rechnen 
und zuweisen, ohne das Hilfskonstrukt "1010110". Aber VHDL ist ja 
sooooooooo logisch aufgebaut, daß all sowas eben nicht geht.

Weswegen ich grad hier mal meinen Frust rauslasse? Weil ich heut grad 
vergeblich versucht habe, einen 4 Bit V/R-Zähler zu schreiben, der nur 
von 6 bis 11 zählt und entsprechend umschlägt, also 10,11,6,7,... bzw. 
beim Runterzählen 7,6,11,10,...

Ich hab's dann per Schematic gemacht: ein Zähler von 0..5 und 
anschließendem Volladder mit ner Konstanten. Krumm, aber geht - und 
weswegen? Weil VHDL ja so benutzerfreundlich und leicht überschaubar ist 
und einem die Arbeit abnimmt...

Nix für ungut, schönen Abend noch.

W.S.

von Da D. (dieter)


Lesenswert?

W.S. schrieb:
> Aber mal abgesehen davon ärgert mich VHDL von Grund auf. Strenge
> Typprüfungen mögen ja nett gedacht sein, aber wie immer: "Gut gemeint
> ist das Gegenteil von gut gemacht". Genau deshalb hat man beim Bauen mit
> CPLD's und FPGA's den meisten Streß mit dem Kämpfen gegen die
> Programmiersprache

Ich fühle mit dir! Ich habe mich auch  heute einige Stunden mit den 
verschiedenen Datentypen, überladenen Operatoren und gefühlten 20 
verschiedenen Konvertierungsfunktionen rumgeärgert.

Mal wird gar kein passender Operator gefunden, wenn man was ändert, 
meckert der Synthesizer statdessen darüber, das 3 verschiedenen gefunden 
werden... Die reinste Seuche...

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


Lesenswert?

W.S. schrieb:
> Aber mal abgesehen davon ärgert mich VHDL von Grund auf.
Dreh den Spieß um. Ärgere VHDL... ;-)

W.S. schrieb:
> versucht habe, einen 4 Bit V/R-Zähler zu schreiben, der nur
> von 6 bis 11 zählt und entsprechend umschlägt, also 10,11,6,7,...
> bzw. beim Runterzählen 7,6,11,10,...
Ich würde das mit einem integer machen:
1
  process begin
2
      wait until rising_edge(clk);
3
      if up='1' ten
4
         if cnt=11 then 
5
            cnt<=6;
6
         else
7
            cnt <= cnt+1;
8
         end if;
9
      else
10
         if cnt=6 then 
11
            cnt<=11;
12
         else 
13
            cnt <= cnt-1;
14
         end if;
15
      end if;
16
  end process;
17
 
18
  ausgang[3 downto 0] <= std_logic_vector(to_unsigned(cnt,4));
Sollte so passen... ;-)

Da Dieter schrieb:
> gefühlten 20 verschiedenen Konvertierungsfunktionen rumgeärgert.
Ich kanns nur wiederholen: ich komme mit 2 Konvertierungen und 2 Casts 
durch Leben... ;-)
http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html

von berndl (Gast)


Lesenswert?

W.S. schrieb:
> Aber mal abgesehen davon ärgert mich VHDL von Grund auf. Strenge
> Typprüfungen mögen ja nett gedacht sein, aber wie immer: "Gut gemeint
> ist das Gegenteil von gut gemacht". Genau deshalb hat man beim Bauen mit
> CPLD's und FPGA's den meisten Streß mit dem Kämpfen gegen die
> Programmiersprache. Warum kann man nicht einen Integertypen einfach
> deklarieren und dann benutzen ohne sich mit Konvertierungen und so
> unsinnigen "Fehlern" wie "diese Operation ist auf diesen Typ nicht
> anwendbar" herumzuschlagen? Ein OTTOKAR: integer(7 downto 0) ist
> sowohl eine Zahl als auch ein Bitvektor, verdammt nochmal! Bei jedem
> integer gibt es zwangsweise ein Bit mit dem Wert 2^0 und wenn er 7
> downto 0 deklariert ist, dann gibt es auch 2^1 bis 2^7, weswegen man
> sehr wohl auf OTTOKAR(5) zugreifen können müßte als auch damit rechnen
> und zuweisen, ohne das Hilfskonstrukt "1010110". Aber VHDL ist ja
> sooooooooo logisch aufgebaut, daß all sowas eben nicht geht.

Dann nimm halt Verilog anstelle von VHDL! Da gibt es nur REG und WIRE, 
dazu ein paar elegante Sachen die VHDL nicht hat. Andererseits kann VHDL 
Dinge die Verilog fremd sind. Man kommt aber mit beiden Sprachen zum 
Ziel...

Abgesehen davon zeigt dein Post m.M. nach eines: Das fehlende 
Grundverstaendnis von Datentypen und dem Librarykonzept von VHDL. Das 
liegt mit ziemlicher Sicherheit daran, dass in den Hochschulen 
offensichtlich Profs lehren, die irgendwann mal was mit VHDL gemacht 
haben und auf dem Stand stehen geblieben sind. Wie Lothar immer 
schreibt: Nimm die numeric_std und die paar Konvertierungen/Casts und 
gut ists.
Und nochwas: Der Unterschied, ob ein std_logic_vector als signed oder 
unsigned behandelt wird kann fuer dich ein Riesenvorteil sein (wenn du 
weisst, was du tust). Und nein, es ist nicht kompliziert!

von W.S. (Gast)


Lesenswert?

berndl schrieb:
> Dann nimm halt Verilog anstelle von VHDL!

Ja, hab ich gemacht, weil mir mein Schematics-Konstrukt nicht recht 
gefallen wollte.

Und?

Nun, es ist ein 3..5 Zeiler bei herausgekommen, der auf Anhieb das 
macht, was ich haben will.

W.S.

P.S.: Eigentlich finde ich Verilog häßlicher als VHDL, weil ich mir die 
1003 Nebeneffekte und Fallstricke nicht merken kann, aber im konkreten 
Fall hat's genau so geholfen, wie ich es gebraucht habe.

von berndl (Gast)


Lesenswert?

W.S. schrieb:
> P.S.: Eigentlich finde ich Verilog häßlicher als VHDL, weil ich mir die
> 1003 Nebeneffekte und Fallstricke nicht merken kann, aber im konkreten
> Fall hat's genau so geholfen, wie ich es gebraucht habe.

Mir persoenlich gefaellt Verilog besser, weil es einfach kompakteren 
Code erlaubt. VHDL ist oft schon eine ueble Tipperei...

Aber andererseits, ein fremder VHDL Code ist normalerweise viel 
einfacher zu durchschauen als ein fremder Verilog Code (eben wegen der 
VHDL-Geschwaetzigkeit).

Aber schoen, dass man die Wahl hat... Eine eklatante Verbesserung ggue. 
Schematics sind beide HDLs

von W.S. (Gast)


Lesenswert?

berndl schrieb:
> Eine eklatante Verbesserung

O Haaaaa!

"eklatante Verbesserung": das war der Freudsche Versprecher des Tages.

Neee, mal ganz im Ernst: Schematics hat genau dort, wo man es genau 
wissen will, seine starke Seite, denn man kann dem Compiler haarklein 
beibringen, was genau man haben will. Schematics ist auch gut als 
Toplevel, wenn man nicht hunderte separat benannter Ports hat. Obendein 
kann man sich damit mit Elektronikern verständigen, die nen Schaltplan 
lesen können - mit VHDL oder Verilog geht das nicht. Dafür ist 
Schematics leider nicht portierbar.

W.S.

von Günter (. (dl4mea)


Lesenswert?

Lothars Typkonvertierungsdiagramm liegt hier einlaminiert ständig 
bereit...

Darf ich mich hier mal anhängen?

Denn ich hab bei der Verwendung von IPs so oft ein in meinen Augen 
häßliches Problem, von dem ich nicht weiß ob ich es geschickt löse. 
Vielleicht kenn ich von VHDL gerade mal 10% oder so.

Also: Ein Multiplier wird mit einem Zähler angesteuert. Der Zähler ist 
in Code ein Integer, das Multiplier-Interface verlangt aber 
std_logic_vector:
1
ENTITY mult15625 IS
2
  PORT
3
  (
4
    dataa    : IN STD_LOGIC_VECTOR (4 DOWNTO 0);
5
 -- datab    : constant 15625
6
    result   : OUT STD_LOGIC_VECTOR (8 DOWNTO 0)
7
  );
8
END mult15625;

sodenn also in meinem Code:
1
   signal clk64_ctr     : integer range 0 to 31 := 0;
2
   signal clk64_ctr_VEC : std_logic_vector ( 4 downto 0);
3
4
   signal TS_fract500 : integer range 0 to 490;
5
   signal TS_fract500_VEC: std_logic_vector (8 downto 0);
6
7
8
   -- machen wir also erst mal eine Typconvertierung am Input
9
   clk64_ctr_VEC <= std_logic_vector(to_unsigned(clk64_ctr,5));
10
   -- dann lassen wir das rechnen 
11
   TS_fract500_mult : ENTITY work.mult15625 (syn)
12
   port map
13
   (
14
      dataa  => clk64_ctr_VEC,  
15
      result => TS_fract500_VEC
16
   );
17
   -- und das Ergebnis wieder zurück in einen Integer...
18
   TS_fract500 <= to_integer(unsigned(TS_fract500_VEC));

Mich nervt hier daß ich immer zwei std_logic_vector als Signal 
definieren muß und die Umwandlung hinschreiben. Das könnte doch auch 
irgendwie kürzer gehen?

Danke, Günter (dl4mea)

von Duke Scarring (Gast)


Lesenswert?

Günter (dl4mea) schrieb:
> Mich nervt hier daß ich immer zwei std_logic_vector als Signal
> definieren muß und die Umwandlung hinschreiben. Das könnte doch auch
> irgendwie kürzer gehen?
Mir fällt da auf Anhieb auch nix kürzeres ein.
Aber ich hätte mir den Multiplizierer auf unsigned (oder signed?) bzw. 
integer umgeschrieben.

Duke

von Günter (. (dl4mea)


Lesenswert?

Hallo,

danke für die Antwort, aber der Multiplizierer kommt aus dem Wizard, da 
will ich nichts mit der Hand ändern.

Günter (dl4mea)

von Duke Scarring (Gast)


Lesenswert?

Günter (dl4mea) schrieb:
> danke für die Antwort, aber der Multiplizierer kommt aus dem Wizard, da
> will ich nichts mit der Hand ändern.
Wenn Du den Multiplizierer öfters instanziierst, lohnt es sich 
vielleicht einen Wrapper drumzubauen:
1
ENTITY mult15625_int IS
2
  PORT
3
  (
4
    dataa    : IN  integer;
5
 -- datab    : constant 15625
6
    result   : OUT integer
7
  );
8
END mult15625_int;
9
10
architecture wrapper of mult15625_int is
11
12
   signal dataa_VEC : std_logic_vector(4 downto 0);
13
   signal result_VEC: std_logic_vector(8 downto 0);
14
15
begin
16
17
   -- machen wir also erst mal eine Typconvertierung am Input
18
   dataa_VEC <= std_logic_vector(to_unsigned( dataa, 5));
19
   -- dann lassen wir das rechnen 
20
   mult_i0 : ENTITY work.mult15625 (syn)
21
   port map
22
   (
23
      dataa  => dataa_VEC,  
24
      result => result_VEC
25
   );
26
   -- und das Ergebnis wieder zurück in einen Integer...
27
   result <= to_integer(unsigned( result_VEC)); 
28
29
end architecture wrapper;

Duke

von Günter (. (dl4mea)


Lesenswert?

Hi,

naja, der Wrapper machts nicht unbedingt simpler, aber ist eine gute 
Idee.

Günter (dl4mea)

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.