VHDL schnipsel or vectorbits

Wechseln zu: Navigation, Suche

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;