Ich habe im Grunde eine Zeile wie diese in einem VHDL-Code.
entity my_entity is
port(x : in std_logic_vector;
y : in std_logic_vector;
...);
end entity my_entity;
architecture arch of my_entity is
-- declarations...
signal delta : unsigned(...); --correct sizing
signal aux_signal : std_logic; -- correct sizing
signal another_signal : unsigned(...); --correct sizing
begin
delta <= x - y; -- x > y
aux_signal <= or_reduce(std_logic_vector(another_signal(to_integer(delta) downto 1)));
-- other stuff
end architecture arch;
Die Syntax ist in Ordnung (überprüft von ncvhdl), aber wenn ich die Synthese versuche, beschwert sich der Compiler über Zuweisungen wie "aux_signal", die sagen, dass es einen konstanten Wert braucht.
Da ich so eine Aufgabe brauche ... gibt es einen anderen Weg, um dasselbe Ergebnis zu erzielen?
Jeffs for
Schleife ist hier der richtige Ansatz, aber Sie müssen sie nicht in einen Prozess einbetten: Sie kann stattdessen eine Funktion sein, und die meisten Synthesewerkzeuge (möglicherweise nicht alle!) sollten damit korrekt umgehen.
function or_reduce_select (sig : unsigned; mask : natural) return std_logic is
variable or_result : std_logic;
begin
or_result := '0';
for i in 1 to sig'left loop
if i <= mask then
or_result := or_result or sig(i);
end if;
end loop;
return or_result;
end or_reduce_select;
...
aux_signal <= or_reduce_select(another_signal, to_integer(delta));
BEARBEITEN zu: Kommentaren ...
Das Original erfordert unterschiedliche Hardware für unterschiedliche Werte von Delta. Da Delta zur Laufzeit variiert, muss Hardware zur Laufzeit erscheinen und verschwinden.
Schauen Sie sich die Schleife hier an: Die Grenzen 1 to sig'left
sind konstant, also ist die Hardware festgelegt: Stattdessen maskiert die "if" -Bedingung jedes unerwünschte Bit mit einem UND-Gatter - das Gatter ist immer da, sein anderer Eingang ist zur Laufzeit variabel. Somit ist diese Form in Hardware physikalisch realisierbar, während dies bei der ursprünglichen Form nicht der Fall ist.
Vielleicht ist es einfacher, die Hardware zu visualisieren, die dadurch erzeugt wird, wenn wir die Schleife neu schreiben:
for i in 1 to sig'left loop
if i <= mask then
or_result := or_result or sig(i);
end if;
end loop;
in folgender Form
for i in 1 to sig'left loop
or_result := (or_result or sig(i)) and (i <= mask);
end loop;
Das Problem ist hier:
another_signal(to_integer(delta) downto 1)
Slices mit laufzeitvariablen Grenzen werden von der Synthese nicht unterstützt. Wie würde sich das in echte Hardware übersetzen?
Eine ähnliche Funktion könnten Sie mit einer Schleife innerhalb eines Prozesses erreichen:
process (delta, another_signal)
variable or_result : std_logic;
begin
or_result := '0';
for i in 1 to another_signal'left loop
if (i <= to_integer(delta)) then
or_result := or_result or another_signal(i);
end if;
end loop;
aux_signal <= or_result;
end process;
Wenn Sie keinen Prozess verwenden können und die Größe von another_signal
festgelegt ist, könnten Sie Folgendes schreiben:
aux_signal <= another_signal(1) when delta = 1 else
or_reduce(another_signal(2 downto 1) when delta = 2 else
or_reduce(another_signal(3 downto 1) when delta = 3 else
or_reduce(another_signal(4 downto 1) when delta = 4 else
'0';
Ich würde Ihnen dringend empfehlen, Prozesse zu verwenden, auch für asynchrone Logik.
process
Konstrukt zu verwenden?resize
würde zu demselben Problem führen, dass der Parameter nicht konstant ist. Ich habe die Antwort aktualisiert, um einen vollständigen Prozess anzuzeigen.
Benutzer8469759
user_1818839
Benutzer8469759
user_1818839
1 to sig'left
sind konstant, also ist die Hardware festgelegt: Stattdessen maskiert die "if" -Bedingung jedes unerwünschte Bit mit einem UND-Gatter - das Gatter ist immer da, sein anderer Eingang ist zur Laufzeit variabel. Somit ist diese Form in Hardware physikalisch realisierbar, die ursprüngliche Form jedoch nicht.