VHDL-Fehler (einfacher Ausdruck erwartet)

Ich bin neu bei VHDL und habe ein Problem mit meinem Code, das ich anscheinend nicht beheben kann. Wir sollen dies entweder mithilfe der ausgewählten Signalzuweisung oder der Tabellensuche tun. Meins ist eine Art Kombination aus beidem, da wir don't cares für Eingaben verwenden sollen, die nicht passieren.

Der Code soll im Grunde die gleiche Ausgabe für entweder die 2er-Komplementeingabe oder die Offset-Binärdatei liefern. So ist beispielsweise die Dezimalzahl 7 „1111“ im Offset-Binär und „0111“ im Zweierkomplement. Beide Formen sollten eine Ausgabe von "1111100000" erzeugen, abhängig vom Wert des Schalters oe ('1' für Offset-Binär, '0' für Zweierkomplement).

Ich habe meinen Code so weit wie möglich auf dieser Ebene debuggt und verstehe nicht, was ich falsch mache.

Active-HDL gibt mir derzeit Fehler in den Zeilen 48 und 55. Ich erhalte zwei Fehler "einfacher Ausdruck erwartet".

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity pitch_decoder_2 is

    port(d, c, b, a : in  std_logic;
         ob         : in  std_logic;
         led        : out std_logic_vector(9 downto 0));

end pitch_decoder_2;

architecture myarch of pitch_decoder_2 is

    type tbl is array (15 downto 0) of std_logic_vector(9 downto 0);

    constant table : tbl := (
        "1111100000",                   --  7
        "1111100000",                   --  6
        "1111100000",                   --  5
        "1111100000",                   --  4
        "0111100000",                   --  3
        "0011100000",                   --  2
        "0001100000",                   --  1
        "0000100000",                   --  0
        "0000110000",                   -- -1
        "0000111000",                   -- -2
        "0000111100",                   -- -3
        "0000111110",                   -- -4
        "0000111111",                   -- -5
        "0000111111",                   -- -6
        "0000111111",                   -- -7
        "0000111111");                  -- -8

    signal input : std_logic_vector(3 downto 0);
    signal tmp   : std_logic_vector(2 downto 0);
begin
    input <= std_logic_vector' (d, c, b, a);
    tmp   <= std_logic_vector' (c, b, a);

    with input select

        led <= table(to_integer(unsigned(d & tmp)))
        when "0000" | "0001" | "0010" | "0011" |
        "0100" | "0101" | "0110" | "0111" |
        "1000" | "1001" | "1010" | "1011" |
        "1100" | "1101" | "1110" | "1111"
        and ob = '1',

        table(to_integer(unsigned(not d & tmp)))
        when "0000" | "0001" | "0010" | "0011" |
        "0100" | "0101" | "0110" | "0111" |
        "1000" | "1001" | "1010" | "1011" |
        "1100" | "1101" | "1110" | "1111"
        and ob = '0',

        "----------" when others;

end myarch;

Auch wenn Sie irgendwelche Tipps haben, wie ich den Code verbessern kann, während ich die Zuweisungsanweisungen beibehalte, zögern Sie nicht, etwas vorzuschlagen.

als Randbemerkung: Ich würde die qualified_expressionAusdrücke (zB tmp <= std_logic_vector' (c, b, a);) nicht verwenden. Behalte a, b, c und d als unterschiedliche Signale. Kleben Sie sie nicht in einer neuen Art von Typ zusammen.
Zeilennummern würden helfen.

Antworten (3)

with input select 
    led <= table(to_integer(unsigned(d & tmp)))
    when "0000" | "0001" | "0010" | "0011" |
         "0100" | "0101" | "0110" | "0111" |
         "1000" | "1001" | "1010" | "1011" |         
         "1100" | "1101" | "1110" | "1111"
         and ob = '1',
    ...

Der Syntaxfehler tritt bei der „and“-Klausel auf, die nicht Teil einer gültigen „select“-Auswahlliste ist.

Beachten Sie jedoch, dass der "when"-Ausdruck gleichbedeutend mit dem vollständigen Ignorieren der "Eingabe" ist

 with ob select 
     led <= table(to_integer(unsigned(d & tmp))) when '1',
     ...

Sie haben möglicherweise den Irrtum, dass die explizite Angabe aller Kombinationen von '0'- und '1'-Werten für "Eingabe" alle Eingabewerte ausschließt, die 'X', 'U', '-' usw. enthalten (von diesen Symbolen ist nur eines a „egal“).

Tatsächlich kann es in der Simulation tatsächlich funktionieren; Ein wenig Nachdenken wird jedoch zeigen, dass es kein synthetisierbares Hardware-Primitiv gibt, das dies zuverlässig kann, und wenn Sie keine Testbench schreiben, ist dies sicherlich der falsche Ansatz und der einfache Syntaxfehler ist das geringste Ihrer Probleme.

BEARBEITEN: Hier ist eine (ungetestete) Möglichkeit, sowohl eine Tabelle als auch eine ausgewählte Signalzuweisung zu verwenden und die Tabellengröße mit don't cares zu reduzieren. Einige weitere Vereinfachungen sind möglich.

architecture myarch of pitch_decoder_2 is

        type tbl is array (3 downto -4) of std_logic_vector(9 downto 0);

        constant table : tbl := (  
        "0111100000",  --  3
        "0011100000",  --  2
        "0001100000",  --  1
        "0000100000",  --  0
        "0000110000",  -- -1
        "0000111000",  -- -2
        "0000111100",  -- -3
        "0000111110"); -- -4

        signal sel : signed(3 downto 0);

begin

        sel   <= (d xor ob) & c & b & a;

        with sel select led <=
           "1111100000" when "01--",
           table(to_integer(sel)) when "00--" | "11--",
           "0000111111" when "10--",
           "----------" when others;

end myarch;
Ich weiß also, dass ich in einem tatsächlichen Hardwaredesign kein 'X', 'U' oder '-' erhalten sollte, aber ich verstehe nicht, wie diese Kombinationen beim Kompilieren ausgeschlossen werden, wenn nicht alle möglichen Binäreingänge angegeben werden.
Außerdem habe ich dieses Zeug durch Ihre vereinfachte Version ersetzt und erhalte immer noch denselben Fehler in den Zeilen 44 und 45. pastebin.com/Qe9ZvC5s
Der Pastebin-Link ist nicht meine Version
Entfernen Sie dies: wenn ob = '0', "----------" wenn andere;
Der neue Pastebin-Link in meinem obigen Kommentar?
ja ... Ihre Auswahlwerte sind boolesche Ausdrücke, keine std_logic-Werte

Ich denke, Sie sind vielleicht etwas verwirrt darüber, wie die Operatoren "|", "and" und "=" funktionieren und welche relative Priorität sie haben. Vielleicht hilft es, einige Klammern hinzuzufügen, um Ihre Bedeutung zu verdeutlichen.

Sie haben alle möglichen Kombinationen von inputim when, also können Sie diesen Code entfernen. Was bleibt, ist 'if ob='1' oder '0'`

led <= table(to_integer(unsigned(d & tmp))) when ob = '1' else table(to_integer(unsigned(not d & tmp)));

Beachten Sie, dass es kein ob = '0' mehr gibt. Ein Signal ist oder '1 oder '0'. (Okay, das ist nicht wahr, aber Sie könnten die Idee greifen ...). Also, wenn es nicht '1' ist, ist es '0'.

Obwohl dies funktionieren wird, erfüllt es nicht die angegebene Einschränkung, die darin besteht, eine ausgewählte Signalzuweisung zu verwenden. Dies ist eine bedingte Signalzuweisung.