Forum: FPGA, VHDL & Co. std_logic_vector und std_ulogic_vector


von Beginner (Gast)


Lesenswert?

Hallo,

kann mir jemand erklären:

 wieso es möglich ist, std_ulogic Signale an std_logic zu hängen, ebenso 
wie std_ulogic an Ports von einem std_logic_vector, es aber nicht 
möglich ist, einen std_ulogic_vector an einen std_logic_vector zu 
hängen? Der Unterschied zwischen beiden Typen ist mir klar, ich verstehe 
nur nicht, wieso es bei einem  ganzen vektor nicht geht, wohl aber bei 
signalen.

Gibts es dafür irgendwelche Hintergründe? Ich würde mich auch über 
Literaturhinweise freuen!

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


Lesenswert?

Beginner schrieb:
> Gibts es dafür irgendwelche Hintergründe?
Die std_logic_1164 sieht so aus:
1
    TYPE std_ulogic IS ( 'U',  -- Uninitialized
2
                         'X',  -- Forcing  Unknown
3
                         '0',  -- Forcing  0
4
                         '1',  -- Forcing  1
5
                         'Z',  -- High Impedance   
6
                         'W',  -- Weak     Unknown
7
                         'L',  -- Weak     0       
8
                         'H',  -- Weak     1       
9
                         '-'   -- Don't care
10
                       );
11
    -------------------------------------------------------------------    
12
    -- unconstrained array of std_ulogic for use with the resolution function
13
    -------------------------------------------------------------------    
14
    TYPE std_ulogic_vector IS ARRAY ( NATURAL RANGE <> ) OF std_ulogic;
15
                                    
16
    -------------------------------------------------------------------    
17
    -- resolution function
18
    -------------------------------------------------------------------    
19
    FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic;
20
    
21
    -------------------------------------------------------------------    
22
    -- *** industry standard logic type ***
23
    -------------------------------------------------------------------    
24
    SUBTYPE std_logic IS resolved std_ulogic;
25
26
    -------------------------------------------------------------------    
27
    -- unconstrained array of std_logic for use in declaring signal arrays
28
    -------------------------------------------------------------------    
29
    TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic;
Und hier siehst du, dass die Auflösungsfunktion nur für einzelne Bits 
definiert ist.
1
    FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic IS
2
        VARIABLE result : std_ulogic := 'Z';  -- weakest state default
3
    BEGIN
4
        -- the test for a single driver is essential otherwise the
5
        -- loop would return 'X' for a single driver of '-' and that
6
        -- would conflict with the value of a single driver unresolved
7
        -- signal.
8
        IF    (s'LENGTH = 1) THEN    RETURN s(s'LOW);
9
        ELSE
10
            FOR i IN s'RANGE LOOP
11
                result := resolution_table(result, s(i));
12
            END LOOP;
13
        END IF;
14
        RETURN result;
15
    END resolved;
Deshalb findet der & Operator, der ja nur gleiche Datentypen verknüpfen 
kann für die zu verknüpfenden Vektoren keine Umwandlungsmöglichkeit.

Du müsstest also den & Operator überladen, dass auch deine Kombination 
geht:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity sl_sul is
5
    Port ( a    : in   STD_LOGIC_VECTOR  (3 downto 0);
6
           b    : in   STD_LOGIC_VECTOR  (3 downto 0);
7
           au   : in   STD_ULOGIC_VECTOR (3 downto 0);
8
           bu   : in   STD_ULOGIC_VECTOR (3 downto 0);
9
           ab   : out  STD_LOGIC_VECTOR  (7 downto 0);
10
           abu  : out  STD_LOGIC_VECTOR  (7 downto 0);
11
           aub  : out  STD_LOGIC_VECTOR  (7 downto 0);
12
           aubu : out  STD_ULOGIC_VECTOR (7 downto 0));
13
end sl_sul;
14
15
architecture Behavioral of sl_sul is
16
17
    FUNCTION "&" ( a : std_ulogic_vector; b : std_logic_vector  ) RETURN std_logic_vector IS
18
        ALIAS av : std_ulogic_vector ( 1 TO a'LENGTH ) IS a;
19
        ALIAS bv : std_logic_vector ( 1 TO b'LENGTH ) IS b;
20
        VARIABLE result : std_logic_vector ( 1 TO a'LENGTH+b'LENGTH );
21
    BEGIN
22
        FOR i IN av'RANGE LOOP
23
          result(i)          := av(i);
24
        END LOOP;
25
        FOR i IN av'RANGE LOOP
26
          result(i+a'LENGTH) := bv(i);
27
        END LOOP;
28
        RETURN result;
29
    END "&";
30
31
    FUNCTION "&" ( b : std_logic_vector; a : std_ulogic_vector  ) RETURN std_logic_vector IS
32
        ALIAS av : std_ulogic_vector ( 1 TO a'LENGTH ) IS a;
33
        ALIAS bv : std_logic_vector ( 1 TO b'LENGTH ) IS b;
34
        VARIABLE result : std_logic_vector ( 1 TO a'LENGTH+b'LENGTH );
35
    BEGIN
36
        FOR i IN av'RANGE LOOP
37
          result(i)          := av(i);
38
        END LOOP;
39
        FOR i IN av'RANGE LOOP
40
          result(i+a'LENGTH) := bv(i);
41
        END LOOP;
42
        RETURN result;
43
    END "&";
44
45
begin
46
   ab   <= a  & b;             
47
   abu  <= a  & bu;  -- jetzt gehts
48
   aub  <= au & b;   -- jetzt gehts
49
   aubu <= au & bu;
50
end Behavioral;

von Beginner (Gast)


Lesenswert?

Danke für deine Antwort.

Ich meinte allerdings nicht den &-Operator, sondern die gewöhnlichen 
Zuweisungen:

-- Bestehendes VHDL:
a : out std_logic,
b : out std_logic,
a_vector : out std_ulogic_vector(0 to 31),

-- Generierter VHDL-Code:
mb_gpio_data : out std_logic_vector(0 to 31),

-- Anbindung:
 -- das hier funktioniert:
 Inst_test: test PORT MAP(
  mb_gpio_data(31) => a,
  mb_gpio_data(30) => b,
  mb_gpio_data(0 to 29) => open
  );

 -- das hier funktioniert NICHT, ohne zu casten:
 Inst_test: test PORT MAP(
  mb_gpio_data => a_vector
  );

Du meintest ja, dass die Auflösungsfunktion nur für einzelne Bits 
definiert ist. Gibt es dazu einen bestimmten Hintergund? Was ist hier 
der Unterschied zwischen einzelnen Signalen und Vektoren?

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


Lesenswert?

Beginner schrieb:
> Gibt es dazu einen bestimmten Hintergund?
Man macht in VHDL lieber eine explizite und sichtbare Umwandlung, als 
sich auf windige Automatismen zu verlassen.

> Du meintest ja, dass die Auflösungsfunktion nur für einzelne Bits
> definiert ist.
Ich meinte nicht, sondern es ist so. Siehe dazu den Ausschnitt aus 
der std_logic_1164... ;-)

> Was ist hier der Unterschied zwischen einzelnen Signalen und Vektoren?
Die Datentypen!
Nehmen wir mal das hier
   signal onebitvector : std_logic_vector( 0 to 0) := "0";
und das hier
   signal onebitsignal : std_logic := '0';
Hier wird augenscheinlich das selbe gemacht/gemeint/realisiert, aber 
VHDL lässt sowas nicht zu:
   onebitsignal <= onbitvector;
Da muss man schreiben:
   onebitsignal <= onbitvector(0);

von Beginner (Gast)


Lesenswert?

Lothar Miller schrieb:
>> Gibt es dazu einen bestimmten Hintergund?
> Man macht in VHDL lieber eine explizite und sichtbare Umwandlung, als
> sich auf windige Automatismen zu verlassen.
Anscheinend ist es ja problemlos möglich sich bei einzelnen Signalen 
hierauf zu verlassen? Mich interessiert eigentlich nur, wieso dies bei 
einzelnen Signalen so implementiert wurde und bei Vektoren nicht! 
Irgendeinen Grund wird es hierfür doch geben? Wenn man dies generell 
nicht tun sollte, wäre es ja auch nicht nur bei einzelnen Signalen 
realisiert worden.

>> Was ist hier der Unterschied zwischen einzelnen Signalen und Vektoren?
> Die Datentypen!
> Nehmen wir mal das hier
>    signal onebitvector : std_logic_vector( 0 to 0) := "0";
> und das hier
>    signal onebitsignal : std_logic := '0';
> Hier wird augenscheinlich das selbe gemacht/gemeint/realisiert, aber
> VHDL lässt sowas nicht zu:
>    onebitsignal <= onbitvector;
> Da muss man schreiben:
>    onebitsignal <= onbitvector(0);
Ich meinte nicht generell der Unterschied! Der ist klar! Ich meinte den 
Unterschied, wieso es eben bei einzelnen Signalen automatisiert gecastet 
wird und bei einem Vektor nicht. Woran hier der Unterschied liegt, dass 
es beim einen gemacht wird und beim anderen nicht.

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


Lesenswert?

Beginner schrieb:
> Mich interessiert eigentlich nur, wieso dies bei
> einzelnen Signalen so implementiert wurde
Da ist es quasi ein "Abfallprodukt", weil ja der std_logic ein 
Untertyp des std_ulogic ist.

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.