2016-05-10 12 views
0

Ich arbeite zur Zeit auf AES-Verschlüsselungsschlüssel von drei verschiedenen Größen (128.192 und 256 Bit).Variable std_logic_vector oder Array-Eintrag in vhdl

ich mich gefragt, ob ich kann erklären/eine std_logic_vector einer variablen Größe verwenden? Zum Beispiel, kann ich nur einen Eingangsport haben und ich werde erfahren, ob es 128,192 oder 256 Bit basierend auf der Benutzereingabe ist?

Oder, wenn ich die maximale Schlüssellänge, die 256 Bit ist, kann ich einen 128 oder 192 Bit-Schlüssel zu diesem std_logic_vector zuweisen? Oder wird eine Fehlermeldung angezeigt?

+0

Ihre Frage ist nicht klar. Eine Variable ist eine Klasse von Objekten in VHDL, ebenso wie ein Signal. Wenn Sie meinen, einem Zuweisungsziel einen Ausdruck zu liefern, der nicht implizit untertypenkonvertiert werden kann (z. B. wenn die Längen nicht übereinstimmen), wird ein Fehler erzeugt. AES eignet sich zum Laden von Schlüsseln 32 oder 64, länger kann die Synthese entgleisen. Sie können Schichten des Ziel- oder Längenstoppers in jedem Fall für reine Verhaltensmodelle bedingt zuweisen. Siehe IEEE Std 1076-2008 14.7.3.4 Signalaktualisierung und 10.6.2 Einfache Variablenzuweisungen für die Anforderungen für die Konvertierung von Subtypen. – user1155120

+1

Meine Frage ist einfach, anstatt 3 Eingabe-Tasten zu definieren (zB key_128: in: std_logic_vector (127 downto 0) und noch zwei für 192 und 256. Kann ich nur eine Eingabe machen und ich weiß, ob es 128,192,256 basierend auf dem Benutzer ist Eingabe – Aquamarine7even

+1

Muss die Länge zur Laufzeit oder nur zur Kompilierungszeit variabel sein Soll die Synthese oder nur die Simulation gesteuert werden? –

Antwort

0

Wenn sich die Schlüsselgröße zur Laufzeit ändert, müssen Sie die entsprechenden Objekte (Signale, Konstanten, Variablen) mit der maximal möglichen Größe deklarieren. Die tatsächliche Schlüssellänge wird dann durch ein anderes Signal oder eine Variable definiert. Die maximale Größe kann wie folgt definiert werden. Wenn Sie ein Objekt vom Typ std_logic_vector mit der maximal möglichen Größe deklarieren, führt die Zuweisung eines kürzeren std_logic_vector zu einem Fehler. Sie müssen die rechte Seite neben der Zuweisung zunächst auf die Größe des Zielobjekts erweitern, z. mit dem folgenden resize Funktion aus dem PoC Library, wo ich einer der Autoren bin:

function resize(vec : std_logic_vector; length : natural; fill : std_logic := '0') return std_logic_vector is 
constant high2b : natural := vec'low+length-1; 
    constant highcp : natural := imin(vec'high, high2b); 
variable res_up : std_logic_vector(vec'low to high2b); 
variable res_dn : std_logic_vector(high2b downto vec'low); 
begin 
if vec'ascending then 
    res_up := (others => fill); 
    res_up(vec'low to highcp) := vec(vec'low to highcp); 
    return res_up; 
else 
    res_dn := (others => fill); 
    res_dn(highcp downto vec'low) := vec(highcp downto vec'low); 
    return res_dn; 
    end if; 
end function; 

Zum Beispiel gegeben eine 128-Bit-std_logic_vector genannt source, kann dies mit bis zu 256 Bit Größe neu sein:

resize(source, 256) -- returns a 256-bit std_logic_vector 

Die Funktion funktioniert wie die resize Funktion auf unsigned und signed aus Paket numeric_std.


Wenn die Schlüsselgröße bei der Kompilierung (elaboraton) Zeit bekannt ist, dann werden Sie haben zwei Möglichkeiten. Ein üblicher Ansatz ist die Schlüsselgröße von einem konstanten und Hindurchführen des Schlüsselgröße über Generika Subkomponenten zu definieren. Die folgende Einheit test hat eine generische SIZE den Schlüssel Größe angeben. Die Länge der Ports sowie andere Objekte können jetzt abhängig von diesem generic definiert werden.

library ieee; 
use ieee.std_logic_1164.all; 

entity test is 
    generic (
    SIZE : positive := 128); -- the default value can be omitted 
    port (
    x : in std_logic_vector(SIZE-1 downto 0); 
    y : out std_logic_vector(SIZE-1 downto 0)); 
end entity test; 

architecture rtl of test is 
begin -- architecture rtl 
    y <= not x; 
end architecture rtl; 

Der generische kann nun während der Instanziierung dieser Entität, beispielsweise gebunden werden:

library ieee; 
use ieee.std_logic_1164.all; 

entity test_tb is 
end entity test_tb; 

architecture rtl of test_tb is 
    constant SIZE : positive := 192; 
    signal x : std_logic_vector(SIZE-1 downto 0) := (others => '0'); 
    signal y : std_logic_vector(SIZE-1 downto 0); 
begin -- architecture rtl 

    dut: entity work.test 
    generic map (
     SIZE => SIZE) 
    port map (
     x => x, 
     y => y); 

end architecture rtl; 

Natürlich ist die Länge der Istdaten (rechte Seite in Port Karte) muss das Match Länge der Formals (linke Seite in der Portmap). Dieser Ansatz wird von allen (Haupt) VHDL-Synthesewerkzeugen unterstützt. Wenn Standardwerte für die Generika vorhanden sind, dann test können direkt als Top-Level-Modul synthetisiert werden.


Die zweite Option, für eine feste Schlüssel-Größe während Ausarbeitung wäre unbeschränkten Arrays zu verwenden (std_logic_vector) im Hafen Erklärung der Entität.Die tatsächliche Größe des Arrays werden mit dem atribute length bestimmt, und der tatsächliche Bereich mit dem range Attribut, zum Beispiel:

library ieee; 
use ieee.std_logic_1164.all; 

entity test2 is 
    port (
    x : in std_logic_vector; 
    y : out std_logic_vector); 
end entity test2; 

architecture rtl of test2 is 
    signal z : std_logic_vector(x'range); 
begin -- architecture rtl 
    z <= x; 
    y <= not z; 

    assert false report "x'length=" & integer'image(x'length) severity note; 
end architecture rtl; 

den Bereich (und Länge) der Portsignale wird dann eingeschränkt durch die damit verbundenen tatsächlichen in der Komponente Instanziierung.

Dies funktioniert in der Simulation. Aber, ich bin nicht sicher, ob es von die (Haupt) VHDL-Synthese-Tools unterstützt wird. Für die Synthese von test2 ist natürlich eine andere Entität auf oberster Ebene erforderlich, die die Array-Bereiche test2 bis instanziiert.