Erwartete Werte in VHDL können beim ersten Taktzyklus nicht extrahiert werden

Das folgende VHDL-Design soll die N- ten Bits aus den vier Werten x_0, x_1, x_2 und x_3 extrahieren und bei jedem Takt einen neuen Wert erzeugen, aber das geschieht nicht.

Nachfolgend finden Sie das Design und die generierte Ausgabe für einige erzwungene Werte für x_0 = 1100, x_1 = 0100, x_2 = 0010 und x_3 = 1011.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity gen_input is
    port (x_0,x_1,x_2,x_3 : in std_logic_vector(3 downto 0);
            y : out std_logic_vector(3 downto 0);
            clk : std_logic);
end gen_input;

architecture Behavioral of gen_input is
signal i : integer := 0;    
begin
    inst_process : process (clk,x_3,x_2,x_1,x_0)
                        begin
                        if(clk'event and clk='1') then
                            if(i < 4) then
                            y <= x_3(i)&x_2(i)&x_1(i)&x_0(i);
                            i <= i + 1;
                            else 
                            i <= 0;
                            end if;     
                        end if; 
                        end process inst_process;
end Behavioral;

Die erzeugte Ausgabe:Ausgabe für zugewiesene Werte von x_0, x_1, x_2 und x_3

(1) Klammern runden Ausdrücke unnötig (das ist nicht c), (2) vor 25 Jahren vereinfachte die rise_edge-Funktion die Taktflankenerkennung (3) keine Testbench, also können wir es nicht selbst ausprobieren (4) gibt es eigentlich nicht eine Frage hier und (5) Code scheint genau das zu tun, was ich erwarten würde.
@BrianDrummond, Klammern um Ausdrücke sind nicht erforderlich, aber für einen Autor optional. Ich persönlich finde, dass sie die Testbedingung auf einer Seite von VHDL für den Leser deutlicher und deutlicher machen. Punkt 2 stimmt. Können Sie Punkt 5 zu einer Erklärung oder Antwort erweitern?
@TonyM Sie sind optional, sehen aber für mich einfach nach Unordnung aus. Vielleicht ist es bei jüngeren Lesern, die mit c aufgewachsen sind, anders. Was Punkt 5 betrifft, so sollte jede Erklärung der Signalzuweisungssemantik und der Deltazyklen ausreichen; Wenn sie nicht ganz klar sind, muss der Fragesteller vielleicht eine tatsächliche Frage stellen.
Willkommen auf der Seite. Bitte beachten Sie, dass dies kein kostenloses Designhaus, kein Hausaufgaben-Beantwortungsdienst oder eine technische Online-Enzyklopädie ist, die Ihnen auf Anfrage kopiert wird. Die Leute werden Ihnen helfen, den nächsten Schritt zu tun, wenn Ihre Frage zeigt, dass Sie so viel wie möglich selbst getan haben - was Ihre leider nicht tut. Bitte bearbeiten Sie Ihre Frage und verbessern Sie sie erheblich. Stellen Sie eine spezifische Frage und zeigen Sie Ihre bisherige Arbeit und Ihre bisherigen Ergebnisse sehr detailliert mit einem beliebigen Schema. Je besser die Qualität der Frage, desto besser die Qualität der Antworten, die Sie anziehen werden. Nochmals ein herzliches Willkommen auf der Seite.
Brian hat einen gültigen Punkt über die Funktion "rising_edge". Ein Übergang von „U“ zu „1“ auf clk erfüllt die Bedingung, clk'event and clk='1während sie nicht erfüllt wäre rising_edge(clk), was einen Übergang von „0“ oder „L“ zu „1“ oder „H“ erfordert (Filtern des Parameterwerts und des letzten Werts durch die Funktion An_X01). Beachten Sie, dass der erste Nicht-U-Wert y_gender zweite Bitwert von X_3–X_0 ist. Bitte formulieren Sie eine Frage.
Wenn clk einen Anfangswert von '0' hätte oder Sie rise_edge(clk) verwendet hätten, würden Sie sehen, dass der erste Wert korrekt ausgegeben wird (wobei zu beachten ist, dass i von rechts nach links ordnet). Beachten Sie, was passiert, wenn i = 4 (hier nicht gezeigt).
Die Verwendung der Funktion "rising_edge" löst dies für mich, danke. @TonyM Der Beitrag sollte mich nicht mit der Syntax vertraut machen, die hier nicht Gegenstand der Abfrage ist.

Antworten (1)

und jeden Takt einen neuen Wert schaffen, aber das passiert nicht

Der Grund dafür ist, dass Ihr Code einen Taktzyklus hat, dem kein Ausgang zugewiesen ist:

if(clk'event and clk='1') then
    if(i < 4) then
        y <= x_3(i)&x_2(i)&x_1(i)&x_0(i);
        i <= i + 1;
    else 
        i <= 0; -- here you have no assignment to y
    end if;     
end if;

Außerdem wäre Ihr Code einfacher, wenn Sie ials variableanstelle von deklarieren würden signal, was Sie wahrscheinlich sowieso beabsichtigen. Siehe dies für einige Diskussionen über die Unterschiede.

Dieser Code ist wahrscheinlich das, wonach Sie suchen (als Simulation):

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

entity gen_input is
end gen_input;

architecture Behavioral of gen_input is

    signal y   : std_logic_vector(3 downto 0);
    signal clk : std_logic := '0';

    constant x_0 : std_logic_vector(3 downto 0) := b"1100";
    constant x_1 : std_logic_vector(3 downto 0) := b"0100";
    constant x_2 : std_logic_vector(3 downto 0) := b"0010";
    constant x_3 : std_logic_vector(3 downto 0) := b"1011";

begin

    clkgen: process
    begin
        wait for 10 ns;
        clk <= not clk;
    end process clkgen;

    inst_process : process (clk)
        variable i : natural range 0 to 3 := 0;
    begin
        if rising_edge(clk) then
            y <= x_3(i) & x_2(i) & x_1(i) & x_0(i);
            i := i + 1;
            if i = 4 then
                i := 0;
            end if;
        end if;
    end process inst_process;
end Behavioral;

Beachten Sie, dass Sie, da innerhalb des Prozesses ials deklariert ist variable, inkrementieren iund dann sofort prüfen können, ob es auf 0 zurückgesetzt werden soll. Sie könnten auch Folgendes tun:

if i = 3 then
    i := 0;
else
    i := i + 1;
end if;

aber es ist mehr Tippen und nicht notwendig. In beiden Fällen erhalten Sie am Ende genau dieselbe RTL.

Hier ist die Sim:

Simulation

Und tatsächlich, um mit mir selbst zu streiten, brauche ich die if-Anweisung wahrscheinlich überhaupt nicht, da die Variable i auf nur 2 Bits (für den Bereich 0 bis 3) begrenzt sein wird und einfach auf natürliche Weise überrollen wird. Aber ich konnte die Sim nicht zum Laufen bringen, ohne sie explizit zurückzusetzen. Wahrscheinlich ist das nur eine Sim-Einstellung in Vivado.