VHDL schnipsel or vectorbits
Oder (OR) über alle bits eines Vektor
Aus dem Forum : http://www.mikrocontroller.net/forum/read-9-397817.html
Aufgabe
Wie fasse ich einen STD_LOGIC_VECTOR(15 downto 0) so zusammen, dass das Ausgangssignal '1' ist, sobald eines der Vektor-Bits auf '1' ist? Also eine OR-Verknüpfung über den ganzen Vektor?
Ein OR von allen einzelnen Bits kann es ja wohl nicht sein: out_sig <= '1' when in(0) or in(1) or ... in(15) else '0';
Lösung
Fasst man die Aufgabe wortwörtlich auf, ist die Lösung eine Schleife (LOOP) mit einer Variablen. Codebeispiele finden sich am Schluss. Kürzere Lösungen beruhen auf den Vergleich mit einem konstanten Vector aus bits mit dem Wert '0'. Das Synthesetool setzt einen solchen Vergleich in optimale Hardware um, also wird es alle bits wie gefordert ver- "OR" -en:
Konvertierung nach unsigned und Vergleich
if unsigned(vector) > 0
Größer/Kleiner als Vergleich (magnitude comparator) benötigen meist mehr Chipresourcen als der direkte Vergleich.
Innerhalb Process
Bei der Simulation enstehen (unerwünschte) Ergebnisse falls im vector bits andere Werte als '1' oder '0' aufweisen (z. B. "U" oder "Z").
if vector /= "0000000000000000" then
ausgang <= '1';
else
ausgang <= '0';
end if;
Außerhalb Process
Die Konstante wird hier in Hex geschrieben. Statt "IF" (erfordert Process) wird eine bedingte Zuweisung beschrieben.
vector_or <= '0' when oder_vector = X"0000" else '1';
Mithilfe von 'range anstatt einer Konstanten:
vector_or <= '0' when oder_vector = (oder_vector'range => '0') else '1';
Als Schleife im kombinatorischen Process
signal vector_or: std_logic;
process(oder_vector)
variable V_or_tmp;
begin
v_or_tmp := '0';
for i in oder_vector'range loop
v_or_tmp := v_or_tmp or oder_vector(i);
end loop;
vector_or <= v_or_tmp
end process;
Als Funktion
Diese Lösung ist unabhängig von der Bitanzahl des Vectors.
ARCHITECTURE structure OF or_test IS
function or_all (inp : in std_logic_vector) return std_logic is
variable v : std_logic;
begin
v := inp(inp'left);
for i in inp'left to inp'right loop
v := v or inp(i);
end loop;
return v;
end function or_all;
constant inp : std_logic_vector(0 to 11) := X"010";
signal er : std_logic;
BEGIN
er <= or_all(inp);
END ARCHITECTURE structure;
Achtung: die Loop inp'left to inp'right wird nicht durchlaufen, wenn der Vektor 'downto' definiert ist. Siehe Forumsbeiträge.
Folgende Lösung vergleicht die einzelnen Bits auf '1' und bricht die Schleife ab wenn die erste '1' gefunden wurde. In der HW werden dann natürlich alle Bits verglichen.
function or_all (inp : in std_logic_vector) return std_logic is
variable v : std_logic;
begin
for i in inp'range loop
v := inp(i);
exit when v = '1';
v := '0';
end loop;
return v;
end function or_all;