Ich versuche, synthetisierbares VHDL zu erstellen, das einen kontinuierlichen Ein-Bit-Signalstrom an einen von vielen Ausgängen demultiplext. Die Ausgänge, die dieser Stream nicht sendet, sollten auf '0' gesetzt werden. Siehe Bild unten für eine Vorstellung davon, was ich zu erreichen versuche.
Der Code, den ich geschrieben habe, um diese Funktionalität zu erstellen, lautet:
send_s <= (line_select_s => prbs_i(0), others => '0');
wobei 'prbs_i(0)' der Signalstrom ist.
Leider ist dies in Vivado nicht synthetisierbar und gibt den Fehler aus:
[Synth 8-211] could not evaluate expression: aggregate choice expression
Gibt es einen geeigneten Weg, dies zu tun? Das VHDL simuliert gut, wird aber nicht synthetisiert.
Das Problem mit Ihrem Code ist, dass eine Zuweisung des Formulars:
a <= (3 => '0', others => '1');
müssen Konstanten für die zugewiesenen Offsets verwenden (in diesem Fall 3).
Wenn Sie möchten, dass der Offset variiert, müssen Sie ihn in zwei Zuweisungen aufteilen. Beachten Sie, dass dies nur innerhalb eines Prozesses funktioniert; Bei zwei gleichzeitigen Zuweisungen würden Sie auf ein Problem mit mehreren Treibern stoßen.
process (line_select_s, prbs_i)
begin
send_s <= (others => '0');
send_s(line_select_s) <= prbs_i(0);
end process;
Dies funktioniert, weil wir zwar mit der Zuweisung '0'
an den gesamten Vektor beginnen, die letzte Zuweisung an ein bestimmtes Signal in einem Prozess jedoch Vorrang hat.
Eine Alternative ist die Verwendung einer Schleife:
process (line_select_s, prbs_i)
begin
send_s <= (others => '0');
for i in send_s'range loop
if (i = line_select_s) then
send_s(i) <= prbs_i(0);
end if;
end loop;
end process;
Dies hat den Vorteil, dass, wenn Ihr Auswahlsignal einen Versatz darstellen kann, der größer ist als die Breite Ihres Zielvektors, kein Fehler in der Simulation erzeugt wird. Ein Beispielszenario wäre ein 3-Bit-Auswahlsignal, aber ein Zielvektor mit nur 5 Elementen; Das erste Verfahren würde einen Fehler erzeugen, wenn das Auswahlsignal 6, 7 oder 8 darstellen würde, das zweite jedoch nicht.
Als Nebenbemerkung möchten Sie vielleicht einen Prozess wie diesen synchronisieren, wenn Sie die beste Leistung (in Bezug auf die maximale Betriebsfrequenz) aus Ihrem Design herausholen möchten.
Viele Wege sind da. Eine einfache Möglichkeit ist, nach Datenflussmodell:
with line_select_s select
send_s <= (send_s & "0000") when "000",
('0' & send_s & "000") when "001",
("00" & send_s & "00") when "010",
("000" & send_s & '0') when "011";
("0000" & send_s) when "100";
"00000" when others;
user_1818839
send_s(line_select_s) <= prbs_i(0);
: Denken Sie daran, dass dieser Prozess Hardware generieren muss, damit jeder Ausgang das Signal tragen kann (daher die Schleife) und nur den ausgewählten ansteuern kann (daher das if). Die Schleife wird effektiv durch Synthese entrollt, wodurch eine Reihe von Treibern generiert wird, die parallel arbeiten, einer für jeden Ausgang.BenAdamson
user_1818839
beängstigend_jeff
send_s <= (others => '0'); send_s(line_select_s) <= prbs_i(0);
nicht funktionieren würde?beängstigend_jeff
user_1818839
beängstigend_jeff
user_1818839
natural range 0 to 4
(oder der Bereich des Ausgangsports), sodass solche Fehler nicht möglich waren. Aber ich sehe gerne beide Ansätze in der Antwort, man weiß nie, wann die Schleife notwendig sein kann.